1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-30 22:14:58 +03:00
inform7/retrospective/6L02/ni.c

131022 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 <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 "6L02"
#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 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_array_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 specification_array_MT 23
#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 meaning_list_MT 39
#define verb_usage_MT 40
#define preposition_usage_MT 41
#define adjective_list_entry_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 taxon_array_MT 70
#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 invocation_list_array_MT 102
#define invocation_list_entry_array_MT 103
#define description_docket_array_MT 104
#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_token_list_array_MT 109
#define invocation_options_array_MT 110
#define simple_memory_claim_MT 111
#define inv_token_problem_token_MT 112
#define single_integer_array_MT 113
#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 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 combinator_MT 133
#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 NO_MEMORY_TYPES 163 /* 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 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 *) allocate_mem(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--;\
}
#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 NUMBER_OF_MREASONS 13
#define NULL_GENERAL_POINTER (store_gp_null())
#define GENERAL_POINTER_IS_NULL(gp) (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 CONVERSION_ROUTINES(SPECNAME, CONNAME, STRUCTNAME)\
STRUCTNAME *SPECNAME##_spec_to_##STRUCTNAME(specification *spec) {\
if (spec == NULL) internal_error("tried to find " #STRUCTNAME " within NULL type");\
if (!(Specifications__Values__is_actual_CONSTANT_construction(spec, CONNAME))) {\
LOG("Bad spec is: $S\n", spec);\
internal_error("tried to find " #STRUCTNAME " inside SP of wrong type");\
}\
STRUCTNAME *str = RETRIEVE_POINTER_##STRUCTNAME(Specifications__get_structure_field(spec));\
if (str == NULL) internal_error("found NULL " #STRUCTNAME " within " #SPECNAME " type");\
return str;\
}\
specification *STRUCTNAME##_to_##SPECNAME##_spec(STRUCTNAME *str) {\
if (str == NULL) internal_error("tried to make null " #STRUCTNAME " into " #SPECNAME " type");\
specification *spec = Specifications__Values__new_actual_CONSTANT(Kinds__base_construction(CONNAME));\
Specifications__set_structure_field(spec, STORE_POINTER_##STRUCTNAME(str));\
return spec;\
}
#define KCONVERSION_ROUTINES(SPECNAME, STRUCTNAME)\
STRUCTNAME *SPECNAME##_spec_to_##STRUCTNAME(specification *spec) {\
if (spec == NULL) internal_error("tried to find " #STRUCTNAME " within NULL type");\
if (!(Specifications__Values__is_actual_CONSTANT_of_kind(spec, K_##SPECNAME))) {\
LOG("Bad spec is: $S\n", spec);\
internal_error("tried to find " #STRUCTNAME " inside SP of wrong type");\
}\
STRUCTNAME *str = RETRIEVE_POINTER_##STRUCTNAME(Specifications__get_structure_field(spec));\
if (str == NULL) internal_error("found NULL " #STRUCTNAME " within " #SPECNAME " type");\
return str;\
}\
specification *STRUCTNAME##_to_##SPECNAME##_spec(STRUCTNAME *str) {\
if (str == NULL) internal_error("tried to make null " #STRUCTNAME " into " #SPECNAME " type");\
specification *spec = Specifications__Values__new_actual_CONSTANT(K_##SPECNAME);\
Specifications__set_structure_field(spec, STORE_POINTER_##STRUCTNAME(str));\
return spec;\
}
#define OCONVERSION_ROUTINES(STRUCTNAME) \
STRUCTNAME *instance_spec_to_##STRUCTNAME(specification *spec) {\
if (spec == NULL) internal_error("tried to find " #STRUCTNAME " within NULL type");\
if (!(Specifications__Values__is_actual_CONSTANT_object(spec))) {\
LOG("Bad spec is: $S\n", spec);\
internal_error("tried to find " #STRUCTNAME " inside SP of wrong type");\
}\
STRUCTNAME *str = RETRIEVE_POINTER_##STRUCTNAME(Specifications__get_structure_field(spec));\
if (str == NULL) internal_error("found NULL " #STRUCTNAME " within object type");\
return str;\
}
#define RETRIEVE_FROM_SPEC(spec, structure)\
RETRIEVE_POINTER_##structure(Specifications__get_structure_field(spec))
#define ATTACH_TO_SPEC(spec, structure, pointer)\
Specifications__set_structure_field(spec, STORE_POINTER_##structure(pointer))
#define OUTPUT_STREAM STREAM *OUT /* used only as a function prototype argument */
#define PUT(c) stream_putc(c, OUT)
#define STREAM_PUT(stream, c) stream_putc(c, stream)
#define INDENT stream_indent(OUT);
#define STREAM_INDENT(x) stream_indent(x);
#define OUTDENT stream_outdent(OUT);
#define STREAM_OUTDENT(x) stream_outdent(x);
#define SET_INDENT(N) set_stream_indentation(OUT, N);
#define STDOUT stream_get_stdout()
#define STDERR stream_get_stderr()
#define TEMPORARY_STREAM \
char dest[2048];\
STREAM TEMP_stream_structure = stream_new_buffer(2048, dest);\
STREAM *TEMP = &TEMP_stream_structure;
#define CLOSE_TEMPORARY_STREAM \
STREAM_CLOSE(TEMP);
#define STREAM_OPEN_TO_FILE(new, fn, enc) stream_open_to_file(new, fn, enc)
#define STREAM_OPEN_TO_FILE_APPEND(new, fn, enc) stream_open_to_file_append(new, fn, enc)
#define STREAM_OPEN_IN_MEMORY(new) stream_open_to_memory(new, 20480)
#define SMALL_STREAM_OPEN_IN_MEMORY(new) stream_open_to_memory(new, 1024)
#define STREAM_CLOSE(stream) stream_close(stream)
#define STREAM_NEW CREATE(STREAM)
#define STREAM_FLUSH(stream) stream_flush(stream)
#define STREAM_EXTENT(x) stream_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("STREAM not in memory");
#define STREAM_BACKSPACE(x) stream_set_position(x, stream_get_position(x) - 1)
#define STREAM_ERASE_BACK_TO(start_position) stream_set_position(OUT, start_position)
#define STREAM_MIN_ACCESSIBLE_LENGTH 255
#define STREAM_MOST_RECENT_CHAR(x) stream_latest(x)
#define STREAM_COPY(to, from) stream_copy(to, from)
#define STREAM_TEXT(x) stream_get_text(x)
#define SPACE_AT_END_OF_STREAM 100
#define I6_OUTPUT_LEAFNAME "auto.inf"
#define DEBUG_LOG_LEAFNAME "Debug log.txt"
#define PROBLEM_LOG_LEAFNAME "Problems.html"
#define XML_HEADINGS_LEAFNAME "Headings.xml"
#define METADATA_LEAFNAME "Metadata.iFiction"
#define UUID_LEAFNAME "uuid.txt"
#define BLURB_LEAFNAME "Release.blurb"
#define MANIFEST_LEAFNAME "manifest.plist"
#define EPSMAP_LEAFNAME "Map.eps"
#define MAX_FILENAME_LENGTH 522 /* Assuming no leafname exceeds 255 characters */
#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 ISN_CAPITALISE 1 /* capitalise first letter of text */
#define ISN_EXPAND_APOSTROPHES 2 /* sometimes regard |'| as |"| */
#define ISN_RECOGNISE_APOSTROPHE_SUBSTITUTION 4 /* recognise |[']| as a literal |'| */
#define ISN_RECOGNISE_UNICODE_SUBSTITUTION 8 /* recognise |[unicode N]| as a literal char */
#define ISN_DEQUOTE 16 /* ignore initial and terminal |"| pair, e.g., render |"fish"| as |fish| */
#define ISN_FOR_ARRAY 32 /* force use of |@{xx}| form not |@@ddd| */
#define ISN_BOX_QUOTATION 64 /* format line breaks into text for an I6 |box| statement */
#define ISN_RAW 128 /* ignore everything except capitalisation and dequoting */
#define MAX_UNISUB_LENGTH 128
#define MAX_NAMESPACE_PREFIX_LENGTH 20 /* when |L_| and a number are added, we are within 31 chars */
#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 /* and 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 MISCELLANEOUS_LEXE 8 /* 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) internal_error_fn(X, __FILE__, __LINE__)
#define internal_error_tree_unsafe(X) internal_error_tu_fn(X, __FILE__, __LINE__)
#define internal_error_if_node_type_wrong(X, Y) nodal_check(X, Y, __FILE__, __LINE__)
#define internal_error_on_node_type(X) 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__Telemetry__ensure_file();\
STREAM_WRITE(telmy, "Problem %s issued from %s, line %d\n", sigil, file, line);\
}\
sigil_of_latest_problem = sigil;\
if (echo_problem_message_sigils) STREAM_WRITE(STDERR, "Problem__ %s\n", sigil);
#define PASS_SIGIL sigil, file, line
#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 MAXIMUM_MLC_BACKTRACE 1000
#define CLEAR_MLC_BACKTRACE mlc_backtrace_sp = 0;
#define RECORD_MLC_BACKTRACE \
if (mlc_backtrace_sp >= MAXIMUM_MLC_BACKTRACE)\
internal_error("MLC backtrace stack overflow");\
mlc_backtrace[mlc_backtrace_sp] = ml;\
mlc_backtrace_at[mlc_backtrace_sp++] = (char *) __func__;
#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 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
#define ORIGIN_WAS_USER_EXTENSIONS_AREA 2
#define ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA 3
#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 compare_word(w, voc) (Text__word(w) == (voc))
#define compare_words(w1, w2) (Text__word(w1) == Text__word(w2))
#define STRING_TOLERANCE_LIMIT 70
#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, w1, w2) { w1 = nt->range_result_w1[N]; w2 = nt->range_result_w2[N]; }
#define PUT_RW(nt, N, w1, w2) { nt->range_result_w1[N] = w1; nt->range_result_w2[N] = w2; }
#define INHERIT_RANGES(from, to) {\
int i;\
for (i=1; i<MAX_RANGES_PER_PRODUCTION; i++) { /* not copying range 0 */\
to->range_result_w1[i] = from->range_result_w1[i];\
to->range_result_w2[i] = from->range_result_w2[i];\
}\
}
#define CLEAR_RW(from) {\
int i;\
for (i=0; i<MAX_RANGES_PER_PRODUCTION; i++) { /* including range 0 */\
from->range_result_w1[i] = -1;\
from->range_result_w2[i] = -1;\
}\
}
#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 = find_nonterminal(Text__Vocabulary__entry_for_text(quotedname));\
identifier->result_compositor = identifier##C;
#define INTERNAL_NONTERMINAL(quotedname, identifier, min, max)\
identifier = find_nonterminal(Text__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 ROOT_NT 1 /* Only one such node exists: the tree root */
#define BIBLIOGRAPHIC_NT 2 /* For the initial title sentence */
#define HEADING_NT 3 /* "Chapter VIII: Never Turn Your Back On A Shreve" */
#define INCLUDE_NT 4 /* "Include School Rules by Argus Filch" */
#define BEGINHERE_NT 5 /* "The Standard Rules begin here" */
#define ENDHERE_NT 6 /* "The Standard Rules end here" */
#define SENTENCE_NT 7 /* "The Garden is a room" */
#define ROUTINE_NT 8 /* "Instead of taking something, ..." */
#define INFORM6CODE_NT 9 /* "Include (- ... -) */
#define TABLE_NT 10 /* "Table 1 - Counties of England" */
#define EQUATION_NT 11 /* "Equation 2 - Newton's Second Law" */
#define TRACE_NT 12 /* A sentence consisting of a single asterisk, perhaps followed by quoted text */
#define RELATIONSHIP_NT 13 /* "on" */
#define CALLED_NT 14 /* "On the table is a container called the box" */
#define WITH_NT 15 /* "The footstool is a supporter with capacity 2" */
#define AND_NT 16 /* "whisky and soda" */
#define KIND_NT 17 /* "A woman is a kind of person" */
#define X_OF_Y_NT 18 /* "description of the painting" */
#define VERB_NT 19 /* "is" */
#define CREATED_NT 20 /* "a vehicle called Sarah Jane's car" */
#define PROPER_NOUN_NT 21 /* "the red handkerchief" */
#define PROPERTY_LIST_NT 22 /* "capacity 2" */
#define FROM_NT 23 /* "East from the Garden is the Grove" */
#define COMMAND_NT 24 /* "change the Marble Door to open" */
#define ALLOWED_NT 25 /* "An animal is allowed to have a description" */
#define EVERY_NT 26 /* "every container" */
#define COMMON_NOUN_NT 27 /* "a container" */
#define ACTION_NT 28 /* "taking something closed" */
#define ADJECTIVE_NT 29 /* "open" */
#define PROPERTYCALLED_NT 30 /* "A man has a number called age" */
#define TOKEN_NT 31 /* Used for tokens in grammar */
#define HIGHEST_NODE_TYPE 32 /* Well, actually the highest plus 1 */
#define implicit_in_creation_of_ANNOT 1 /* |inference_subject|: for assemblies */
#define implicitness_count_ANNOT 2 /* int: keeping track of recursive assemblies */
#define relationship_ANNOT 3 /* |binary_predicate|: for RELATIONSHIP nodes */
#define resolved_ANNOT 4 /* int: temp storage when resolving NPs */
#define negated_boolean_ANNOT 6 /* int: set if adjective meant negatively */
#define verbal_certainty_ANNOT 7 /* int: a certainty level attached to a sentence */
#define slash_class_ANNOT 8 /* int: used when partitioning grammar tokens */
#define table_cell_unspecified_ANNOT 9 /* int: used to mark table entries as unset */
#define grammar_token_code_ANNOT 10 /* int: used to identify grammar tokens */
#define plural_reference_ANNOT 11 /* int: used by PROPER NOUN nodes for evident plurals */
#define heading_level_ANNOT 12 /* int: for HEADING nodes, a hierarchical level, 0 (highest) to 9 (lowest) */
#define grammar_token_literal_ANNOT 13 /* int: for grammar tokens which are literal words */
#define nounphrase_article_ANNOT 14 /* int: definite or indefinite article: see below */
#define sentence_unparsed_ANNOT 15 /* int: set if verbs haven't been sought yet here */
#define verb_id_ANNOT 16 /* int: identifying what kind of VERB node */
#define relationship_node_type_ANNOT 17 /* int: what kind of inference this assertion makes */
#define evaluation_ANNOT 19 /* |specification|: result of evaluating the text */
#define implicitly_refers_to_ANNOT 20 /* int: this will implicitly refer to something */
#define grammar_token_relation_ANNOT 21 /* |binary_predicate|: for relation tokens */
#define table_cell_allocated_ANNOT 22 /* int: table entry already correctly allocated */
#define multiplicity_ANNOT 23 /* |int|: e.g., 5 for "five gold rings" */
#define interpretation_of_subject_ANNOT 24 /* |inference_subject|: subject, during passes */
#define category_of_I6_translation_ANNOT 25 /* int: what sort of "translates into I6" sentence this is */
#define suppress_heading_dependencies_ANNOT 26 /* int: ignore extension dependencies on this heading node */
#define row_amendable_ANNOT 27 /* int: a candidate row for a table amendment */
#define colon_block_command_ANNOT 28 /* int: this COMMAND uses the ":" not begin/end syntax */
#define aph_ANNOT 30 /* |adjectival_phrase|: which adjective is asserted */
#define creation_proposition_ANNOT 31 /* |pcalc_prop|: proposition which newly created value satisfies */
#define subject_ANNOT 32 /* |inference_subject|: what this node describes */
#define grammar_value_ANNOT 33 /* |specification|: used as a marker when evaluating Understand grammar */
#define nowhere_ANNOT 34 /* |int|: used by the spatial plugin to show this represents "nowhere" */
#define turned_already_ANNOT 35 /* |int|: aliasing like "player" to "yourself" performed already */
#define rulebook_basis_ANNOT 36 /* |kind|: e.g., |K_object| for "object-based" */
#define language_element_ANNOT 37 /* |int|: this node is not really a sentence, but a language definition Use */
#define stored_as_kind_ANNOT 38 /* |kind|: used when creating new names for kinds of value */
#define clears_pronouns_ANNOT 40 /* |int|: this sentence erases the current value of "it" */
#define verb_problem_issued_ANNOT 41 /* |int|: has a problem message about the primary verb been issued already? */
#define log_inclusion_sense_ANNOT 42 /* |int|: should we include or exclude this from the debugging log? */
#define sentence_is_existential_ANNOT 43 /* |int|: such as "there is a man" */
#define lpe_options_ANNOT 44 /* |int|: options set for a literal pattern part */
#define new_relation_here_ANNOT 45 /* |binary_predicate|: new relation as subject of "relates" sentence */
#define action_meaning_ANNOT 46 /* |action_pattern|: meaning in parse tree when used as noun */
#define defn_language_ANNOT 47 /* |natural_language|: what language this definition is in */
#define gender_reference_ANNOT 48 /* |int|: used by PROPER NOUN nodes for evident genders */
#define slash_dash_dash_ANNOT 49 /* |int|: used when partitioning grammar tokens */
#define embodying_heading_ANNOT 50 /* |heading|: for parse nodes of headings */
#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 TREE_START(p) p=tree_root->down,current_sentence=p
#define TREE_NEXT(p) p=p->next,current_sentence=p
#define TREE_LOOP(p) for (TREE_START(p); p; TREE_NEXT(p))
#define MAKE_ANNOTATION_FUNCTIONS(annotation_name, pointer_type)\
void Parser__Nodes__set_##annotation_name(parse_node *pn, pointer_type *bp) {\
pn_annotate_pointer(pn, annotation_name##_ANNOT,\
STORE_POINTER_##pointer_type(bp));\
}\
pointer_type *Parser__Nodes__get_##annotation_name(parse_node *pn) {\
pointer_type *pt = NULL;\
if (Parser__Nodes__has_annotation(pn, annotation_name##_ANNOT))\
pt = RETRIEVE_POINTER_##pointer_type(\
pn_pointer_annotation(pn, annotation_name##_ANNOT));\
return pt;\
}
#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 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=Data__Nametags__name_resolution_data(nt)->next_under_heading)
#define LOOP_OVER_NT_SEARCH_LIST(nt) \
for (nt = nt_search_start; nt; nt = Data__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)?(Parser__Sentences__NPs__new_raw(w1, w2)):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 INFTY 1000000000 /* if ever a node has more than a billion children, we are in trouble anyway */
#define OUTRAGEOUSLY_LARGE_NODE_TYPE 10000
#define MARKED_WITH_CROSS(t) \
((t >= OUTRAGEOUSLY_LARGE_NODE_TYPE + 1) &&\
(t < OUTRAGEOUSLY_LARGE_NODE_TYPE + HIGHEST_NODE_TYPE))
#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 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] = 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 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 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_RIGHT_DOMAIN_SIZE 10000
#define MAX_WORDS_IN_PREPOSITION (MAX_WORDS_IN_ASSEMBLAGE - 2)
#define MAX_WORDS_IN_VERB (MAX_WORDS_IN_ASSEMBLAGE - 4)
#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 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 = aph_get_sorted_definition_list(aph); am; am=am->next_sorted)
#define LITERAL_FORMS_LOOP(lp, K)\
for (lp = Kinds__list_of_literal_forms(K); lp;\
lp=lp->next_for_this_kind)
#define MAX_ELEMENTS_PER_LITERAL 16
#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 == w1) return NULL;\
last_LP_problem_at = w1;
#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 /* see the secondary meaning code below */
#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 END_PHRASE_MC 0x00020000 /* e.g., |end while| */
#define SAY_PHRASE_MC 0x00040000 /* e.g., |say # in words| */
#define PHRASE_CONSTANT_MC 0x00080000 /* 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 USE_OPTION_SMC 0x00000001 /* e.g., |memory economy (option)| */
#define RELATION_SMC 0x00000002 /* e.g., |containment (relation)| */
#define UNICODENAME_SMC 0x00000003 /* e.g., |(Unicode) Greek letter alpha| */
#define RULE_OUTCOME_SMC 0x00000004 /* e.g., |it is very unlikely (outcome)| */
#define ACTION_NAME_SMC 0x00000005 /* e.g., |going action| */
#define RULE_SMC 0x00000006 /* e.g., |ambient sound rule| */
#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 (Data__Instances__of_kind(I, K))
#define LOOP_OVER_ENUMERATION_INSTANCES(I) \
LOOP_OVER(I, instance)\
if (Kinds__is_an_enumeration(Data__Instances__kind(I)))
#define LOOP_OVER_OBJECT_INSTANCES(I) \
LOOP_OVER_INSTANCES(I, K_object)
#define MAX_OBJECT_INDEX_DEPTH 10000
#define ML_PLAIN(w1, w2) Parser__SP__MeaningLists__new_with_words(UNPARSED_ML, w1, w2)
#define MLD_0(x) \
NULL; *XP = Parser__SP__MeaningLists__new_with_words(x, w1, w2);
#define MLD_1(x, y)\
NULL; *XP = Parser__SP__MeaningLists__new_with_words(x, w1, w2);\
(*((meaning_list **) XP))->child = y;
#define MLD_2(x, y, z)\
NULL; { meaning_list *ml = Parser__SP__MeaningLists__new_with_words(x, w1, w2);\
ml->child = y;\
ml->child->sibling = z; *XP = ml; }
#define MLI_0(i, x)\
NULL; { *XP = Parser__SP__MeaningLists__new_with_words(i, w1, w2);\
meaning_list *inter = Parser__SP__MeaningLists__new_with_words(x, w1, w2);\
(*((meaning_list **) XP))->child = inter; }
#define MLI_1(i, x, y)\
NULL; { *XP = Parser__SP__MeaningLists__new_with_words(i, w1, w2);\
meaning_list *inter = Parser__SP__MeaningLists__new_with_words(x, w1, w2);\
(*((meaning_list **) XP))->child = inter; inter->child = y; }
#define MLI_2(i, x, y, z)\
NULL; { *XP = Parser__SP__MeaningLists__new_with_words(i, w1, w2);\
meaning_list *inter = Parser__SP__MeaningLists__new_with_words(x, w1, w2);\
(*((meaning_list **) XP))->child = inter; inter->child = y;\
((meaning_list *) y)->sibling = z; }
#define MLI_3(i, x, y, z, w)\
NULL; { *XP = Parser__SP__MeaningLists__new_with_words(i, w1, w2);\
meaning_list *inter = Parser__SP__MeaningLists__new_with_words(x, w1, w2);\
(*((meaning_list **) XP))->child = inter; inter->child = y;\
((meaning_list *) y)->sibling = z; ((meaning_list *) z)->sibling = w; }
#define MLI_4(i, x, y, z, w, t)\
NULL; { *XP = Parser__SP__MeaningLists__new_with_words(i, w1, w2);\
meaning_list *inter = Parser__SP__MeaningLists__new_with_words(x, w1, w2);\
(*((meaning_list **) XP))->child = inter; inter->child = y;\
((meaning_list *) y)->sibling = z; ((meaning_list *) z)->sibling = w;\
((meaning_list *) w)->sibling = t; }
#define MLJ_1(i, j, x, y)\
NULL; { *XP = Parser__SP__MeaningLists__new_with_words(i, w1, w2);\
meaning_list *inter = Parser__SP__MeaningLists__new_with_words(j, w1, w2);\
meaning_list *inter2 = Parser__SP__MeaningLists__new_with_words(x, w1, w2);\
(*((meaning_list **) XP))->child = inter;\
inter->child = inter2;\
inter2->child = y; }
#define MLK_1(i, j, k, x, y)\
NULL; { *XP = Parser__SP__MeaningLists__new_with_words(i, w1, w2);\
meaning_list *inter = Parser__SP__MeaningLists__new_with_words(j, w1, w2);\
meaning_list *inter2 = Parser__SP__MeaningLists__new_with_words(k, w1, w2);\
meaning_list *inter3 = Parser__SP__MeaningLists__new_with_words(x, w1, w2);\
(*((meaning_list **) XP))->child = inter;\
inter->child = inter2;\
inter2->child = inter3;\
inter3->child = y; }
#define ABSENT_SUBJECT_ML 0x80000010
#define ACTION_ML 0x80000020
#define ADVERB_ML 0x80000030
#define AL_ML 0x80000040
#define AP_ML 0x80000050
#define CALLED_ML 0x80000058
#define CARRIED_ML 0x80000060
#define CASE_ML 0x80000070
#define OTHERWISE_ML 0x80000080
#define CMD_ML 0x80000090
#define COND_AND_ML 0x800000a0
#define COND_NOT_ML 0x800000b0
#define COND_OR_ML 0x800000c0
#define COND_PAST_ML 0x800000d0
#define COND_PHRASE_ML 0x800000e0
#define COND_ML 0x800000f0
#define DC_ADJS_ML 0x80000100
#define DC_ADJSNOUN_ML 0x80000110
#define DC_NOUN_ML 0x80000130
#define DC_ML 0x80000140
#define DETERMINER_ML 0x80000180
#define INSTEAD_ML 0x80000190
#define LITERAL_ML 0x800001a0
#define LOCAL_ML 0x800001b0
#define MEMBER_OF_ML 0x800001c0
#define ADJ_NOT_ML 0x800001e0
#define NP_ML 0x800001f0
#define OPTION_ML 0x80000200
#define PHR_OPT_ML 0x80000210
#define PHRASE_ML 0x80000220
#define PREP_ML 0x80000240
#define SAY_ML 0x80000250
#define SN_ML 0x80000270
#define STV_ML 0x80000280
#define SV_ML 0x80000290
#define TE_CALLED_ML 0x800002a0
#define TE_EX_VAR_ML 0x800002b0
#define TE_GL_VAR_ML 0x800002c0
#define TE_NEW_VAR_ML 0x800002e0
#define TE_ML 0x800002f0
#define TE_VAR_ML 0x80000300
#define THERE_ML 0x80000310
#define TIME_ML 0x80000320
#define TR_CORR_ML 0x80000330
#define TR_ENTRY_ML 0x80000340
#define TR_IN_ROW_ML 0x80000350
#define TR_LISTED_IN_ML 0x80000360
#define TR_OF_IN_ML 0x80000370
#define TR_ML 0x80000380
#define TYPE_ML 0x80000390
#define UNPARSED_ML 0x800003a0
#define VAL_LIST_ENTRY_ML 0x800003b0
#define VAL_NOTHING_ML 0x800003c0
#define VAL_ML 0x800003d0
#define VAL_PAIR_ML 0x800003e0
#define VAL_PROP_OF_ML 0x800003f0
#define VAL_RESPONSE_ML 0x80000400
#define VALUE_PHRASE_ML 0x80000410
#define VERB_ML 0x80000420
#define VP_ML 0x80000430
#define COMPOSITED_ML 0x80000440
#define EQUATION_INLINE_ML 0x80000450
#define EQUATION_WHERE_ML 0x80000460
#define SAY_VERB_ML 0x80000470
#define SAY_MODAL_VERB_ML 0x80000480
#define SAY_ADJECTIVE_ML 0x80000490
#define LOG_ML_SAFETY_LIMIT 100
#define THE_INFINITE_FUTURE 2147483647
#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 + END_PHRASE_MC + SAY_PHRASE_MC)
#define EXCERPT_MEANING_RELEVANT(ml) \
(no_meanings_tried++, ((mc_bitmap & (ml->em->meaning_code))!=0))
#define EXAMINE_EXCERPT_MEANING_IN_DETAIL \
LOGIF(EXCERPT_PARSING, "Trying $M (parsing mode %d)\n", ml->em, 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 NOW_CONVERTING(pr) \
specification *spec = NULL;\
RECORD_MLC_BACKTRACE;\
if ((ml == NULL) || (Parser__SP__MeaningLists__production(ml) != pr))\
internal_error("Non-" #pr " production");
#define NOW_CONVERTING_SUBTREE(pr) \
NOW_CONVERTING(pr)\
if (Parser__SP__MeaningLists__down(ml) == NULL)\
internal_error("Childless " #pr " production");
#define NOW_CONVERTING_LEAF(pr) \
NOW_CONVERTING(pr)\
if (Parser__SP__MeaningLists__down(ml))\
internal_error("Non-leaf " #pr " production");
#define CHILD_UNCONVERTIBLE(pr) \
internal_error("Unknown child of " #pr " production");\
return Specifications__Unknown__new(-1, -1);
#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__Propositions__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 128 /* in fact 40 is plenty, but to be on the safe side */
#define MAX_I6_SCHEMA_ATTEMPT 512 /* 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=first_base_k(); K; K = 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 8
#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 CUBEROOT_OPERATION 7 /* cube root -- similarly unary */
#define EQUALS_OPERATION 8 /* set equal -- used only in equations */
#define POWER_OPERATION 9 /* raise to integer power -- used only in equations */
#define UNARY_MINUS_OPERATION 10 /* unary minus -- used only in equations */
#define TOTAL_OPERATION 11 /* 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__get_dim_rules(left_operand),\
dimr = (dimrs)?(dimrs->multiplications):NULL,\
wn = (dimr)?(dimr->word_ref1):-1,\
right_operand = (dimr)?(dimr->right):0,\
outcome_type = (dimr)?(dimr->outcome):0;\
dimr;\
dimr = dimr->next,\
wn = (dimr)?(dimr->word_ref1):-1,\
right_operand = (dimr)?(dimr->right):0,\
outcome_type = (dimr)?(dimr->outcome):0)
#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 ALWAYS_MATCH 2 /* provably correct at compile time */
#define SOMETIMES_MATCH 1 /* provably reduces to a check feasible at run-time */
#define NEVER_MATCH 0 /* neither of the above */
#define UNKNOWN 1 /* "arfle barfle gloop" */
#define MATCHING_FMY 5
#define NEW_LOCAL_VARIABLE_NAME_SPC 6 /* "nonexisting number variable" */
#define VALUE_FMY 10
#define CONSTANT_SPC 11 /* "7", "the can't lock a locked door rule", etc. */
#define PHRASE_TO_DECIDE_VALUE_SPC 12 /* "holder of the black box" */
#define STORAGE_FMY 20
#define LOCAL_VARIABLE_SPC 21 /* "the running total", say */
#define NONLOCAL_VARIABLE_SPC 22 /* "the location" */
#define PROPERTY_VALUE_SPC 23 /* "the carrying capacity of the cedarwood box" */
#define TABLE_ENTRY_SPC 24 /* "tonnage in row X of the Table of Corvettes" */
#define LIST_ENTRY_SPC 25 /* "item 4 in L" */
#define CONDITION_FMY 30
#define LOGICAL_AND_SPC 31 /* "A and B" */
#define LOGICAL_OR_SPC 32 /* "A or B" */
#define TEST_PROPOSITION_SPC 33 /* if "the cat is on the mat" */
#define TEST_PHRASE_OPTION_SPC 34 /* "giving full details", say */
#define TEST_ACTION_SPC 35 /* "going nowhere in the Confusing Labyrinth" */
#define TEST_PAST_ACTION_SPC 36 /* "we have gone nowhere" */
#define NOW_PROPOSITION_SPC 37 /* now "the cat is on the mat" */
#define PHRASE_TO_DECIDE_IF_SPC 38 /* "in darkness" */
#define DESCRIPTION_SPC 39 /* "open door which is lockable", "a container" */
#define COMMAND_FMY 40
#define TO_PHRASE_SPC 41 /* "award 5 points" */
#define END_BLOCK_SPC 42 /* "end while" */
#define OTHERWISE_SPC 43 /* "otherwise" */
#define CASE_SPC 44 /* "-- V" value in a switch */
#define RULEBOOK_OUTCOME_PHRASE_SPC 45 /* "persuasion succeeds" */
#define TRY_ACTION_SPC 46 /* "try dropping the eustace diamonds" */
#define NO_SPEC_CONTEXTS 5
#define TYPE_EXPECTED_SPCONTEXT 1
#define TYPE_FOUND_SPCONTEXT 2
#define COMPILED_SPCONTEXT 4
#define PARSED_SPCONTEXT 8
#define TYPE_PARSED_SPCONTEXT 16
#define INITIAL_ID_TABLE_SIZE 50 /* must be at least 50 */
#define MAXIMUM_SPEC_ARGUMENTS 4 /* must be $\leq 7$; |TABLE_ENTRY_SPC|, the current record-holder, needs 4 */
#define GENERIC_DATA_SPFLAG 0x00000001 /* generic rather than actual data */
#define ACTION_FOR_OTHER_SPFLAG 0x00000002 /* |ACTION_SPC|: asking someone else to do this? */
#define CONDITION_NEGATED_SPFLAG 0x00000004 /* |CONDITION_FMY|: if set, negates the condition */
#define RECORD_AS_SELF_SPFLAG 0x00000008 /* |PROPERTY_VALUE_SPC|: record recipient as |self| when writing this */
#define SELF_OBJECT_SPFLAG 0x00000010 /* |CONSTANT_SPC-object|: this represents |self| at run-time */
#define NOTHING_OBJECT_SPFLAG 0x00000020 /* |CONSTANT_SPC-object| objects: this represents |nothing| at run-time */
#define COERCED_SPFLAG 0x00000040 /* warning: do not trust my value in a cache, I've been coerced! */
#define EXPLICIT_LITERAL_SPFLAG 0x00000080 /* |CONSTANT_SPC-number| or |-text|: my value is an explicit integer or text */
#define COMPOSITED_SPFLAG 0x00000080 /* |DESCRIPTION_SPC|: I arise from a composite determiner like "somewhere" */
#define BASE_OF_SPDATA_ID 0x00000100 /* these bits hold a |*_SPDATA| constant showing how we use... */
#define SPDATA_ID_MASK 0x00000f00
#define BASE_OF_SPDATA 0x00001000 /* ...these bits */
#define SPDATA_MASK 0x0ffff000
#define NO_SPDATA 0 /* the data portion of the bitmap isn't used */
#define PHRASE_OPTION_SPDATA 1 /* |TEST_PHRASE_OPTION_SPC|: $2^i$ where $i$ is the option number, $0\leq i<16$ */
#define CONSTANT_ENUMERATION_SPDATA 2 /* |CONSTANT_SPC|: which one from an enumerated kind */
#define RESPONSE_CODE_SPDATA 3 /* |CONSTANT_SPC|: for responses only */
#define GRAMMAR_TOKEN_SCORE_SPDATA 4 /* score applied to this grammar token */
#define TEXT_UNESCAPED_SPDATA 5 /* flag used only for literal texts */
#define BASE_OF_ARGC 0x10000000 /* these bits hold the argument count, from 0 to |MAXIMUM_SPEC_ARGUMENTS| */
#define ARGC_MASK 0x70000000
#define ASSOCIATED_KIND_SPCFLAG 0x00000001 /* allowed to have an associated kind */
#define TENSE_SPCFLAG 0x00000002 /* allowed to have a tense */
#define PROPOSITION_SPCFLAG 0x00000004 /* allowed to have a proposition */
#define DOCKET_SPCFLAG 0x00000008 /* allowed to have a docket */
#define ARGUMENTS_SPCFLAG 0x00000010 /* allowed to have one or more arguments */
#define INVLIST_SPCFLAG 0x00000020 /* allowed to have an invocation list */
#define PHRASAL_SPCFLAG 0x00000040 /* this species compiles to a function call */
#define EVALUATING_SPCFLAG 0x00000080 /* this species compiles to a value */
#define SPECIES_MULTIPLIER 100
#define VALUE_EXPCON 0
#define CONDITION_EXPCON 1
#define VOID_EXPCON 2
#define TYPE_EXPCON 3
#define DESCRIPTIVE_TYPE_EXPCON 4
#define NUMBER_OF_EXPCONS 5
#define MAXIMUM_CACHE_SIZE 20 /* a Goldilocks value: too high slows us down, too low doesn't cache enough */
#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 DEFINING_TEXT_SUB_CMODE 0x00002000 /* compiling the text of a text substitution */
#define CONSTANT_CMODE 0x00004000 /* compiling values in a constant context */
#define NONE_CCM 1 /* constant values of this kind cannot exist */
#define LITERAL_CCM 2 /* the literal-parser is used to resolve text of SP to a number */
#define NAMED_CONSTANT_CCM 3 /* a |instance| structure is pointed to */
#define SPECIAL_CCM 4 /* special code specific to the kind of value is needed */
#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__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__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, DATA##_spec_to_##STRUCTURE)
#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(ale, spec)\
for (ale = (spec_find_docket(spec, FALSE))?((spec_find_docket(spec, FALSE))->adjectives_applied):NULL;\
ale; ale=ale->next)
#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 (problem_threshold >= 1) return NEVER_MATCH; /* meaning "suppress even gross problems" */
#define THIS_IS_AN_ORDINARY_PROBLEM \
if (problem_threshold >= 2) return NEVER_MATCH; /* meaning "suppress ordinary problems" */
#define LOG_STAGE_LEFT(stage) \
LOGIF(MATCHING, "[%d%s] %s $S",\
unique_TR_call_identifier,\
(problem_threshold == 0)?"":\
((problem_threshold == 1)?"-quiet":"-silent"), stage, found);
#define LOG_STAGE(stage) \
{ LOG_STAGE_LEFT(stage); LOGIF(MATCHING, "\n"); }
#define SAY_UTSHAPE 1
#define LIST_UTSHAPE 2
#define NO_UTSHAPE 3
#define INVALID_CP_BIT 1
#define WHENWHILE_CP_BIT 2
#define THIS_IS_AN_INTERESTING_PROBLEM \
Code__Invocations__set_flag(inv, INTERESTING_PROBLEM_INVFLAG);\
invocation_passed = FALSE;\
if (issue_interesting_problems)
#define SUPPRESS_IMPLIED_NEWLINES_INVFLAG 0x00000001 /* in saying of literal text ending with punctuation */
#define INSTEAD_INVFLAG 0x00000002 /* has the "instead" keyword been prefixed or suffixed? */
#define SAVE_SELF_INVFLAG 0x00000004 /* save the |self| value on I6 stack around this invocation */
#define PASSED_INVFLAG 0x00000008 /* once type-checked: did this pass type checking? */
#define UNPROVEN_INVFLAG 0x00000010 /* once type-checked: will this need run-time checking? */
#define GROSSLY_FAILED_INVFLAG 0x00000020 /* once type-checked: oh, this one failed big time */
#define TESTED_INVFLAG 0x00000040 /* has been type-checked */
#define INTERESTING_PROBLEM_INVFLAG 0x00000080 /* an interesting problem message could be produced about the way this failed */
#define BASE_OF_GROUP 0x00000100 /* to which group this belongs: 0, 1, 2, ... */
#define GROUP_MASK 0x000FFF00 /* up to a possible 4095 */
#define BASE_OF_USN 0x00100000 /* unsorted position in list, 0 up to 2047 */
#define USN_MASK 0x7FF00000
#define LOOP_THROUGH_TOKENS_PARSED_IN_INV(inv, spec)\
int lttpii_counter, lttpii_upto = Code__Invocations__get_number_tokens(inv);\
for (lttpii_counter=0,\
spec = (lttpii_counter < lttpii_upto)?\
Code__Invocations__get_token_as_parsed(inv, lttpii_counter):NULL;\
lttpii_counter < lttpii_upto;\
lttpii_counter++,\
spec = (lttpii_counter < lttpii_upto)?\
Code__Invocations__get_token_as_parsed(inv, lttpii_counter):NULL)
#define MAX_INVOCATIONS_PER_PHRASE 4096
#define INVOCATION_VARIABLE(inv) \
invocation *inv;\
invocation_list_entry *inv##_ent;\
int inv##_pos;
#define LOOP_THROUGH_INVOCATION_LIST(inv, invl)\
for (inv##_ent = invl->list_head, inv##_pos = 0,\
inv = (inv##_ent)?inv##_ent->listed_inv:NULL;\
inv##_ent;\
inv##_ent = inv##_ent->next, inv##_pos++,\
inv = (inv##_ent)?inv##_ent->listed_inv:NULL)
#define LOOP_THROUGH_PART_OF_INVOCATION_LIST(inv, invl, p, from, size)\
for (inv##_pos = 0, inv##_ent = invl->list_head;\
((inv##_pos<from) && (inv##_ent));\
inv##_pos++, inv##_ent = inv##_ent->next) ;\
for (inv##_pos = 0, p = 0, inv = (inv##_ent)?inv##_ent->listed_inv:NULL;\
((inv##_pos<size) && (inv##_ent));\
inv##_pos++, p++, inv##_ent = inv##_ent->next,\
inv = (inv##_ent)?inv##_ent->listed_inv:NULL)
#define LOOK_AHEAD_THROUGH_INVOCATION_LIST(inv, from, invl)\
for (inv##_ent = from##_ent, inv##_pos = from##_pos,\
inv = (inv##_ent)?inv##_ent->listed_inv:NULL;\
inv##_ent;\
inv##_ent = inv##_ent->next, inv##_pos++,\
inv = (inv##_ent)?inv##_ent->listed_inv:NULL)
#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__Traverse__begin();\
instance *I_of;\
inference_subject *infs;\
if (Kinds__definite(K))\
LOOP_OVER_INSTANCES(I_of, K)\
for (infs = Data__Instances__as_subject(I_of); infs; infs = World__Subjects__narrowest_broader_subject(infs))\
LOOP_OVER_PERMISSIONS_FOR_INFS(pp, infs)\
if (((prn = World__Permissions__get_property(pp))) &&\
(Properties__Traverse__visited(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 *) (Data__Instances__as_subject(I))->plugin_subj[name##_plugin->allocation_id])
#define CREATE_PF_DATA(name, S)\
(S)->plugin_subj[name##_plugin->allocation_id] = (void *) (name##_plugin_new_data(S));
#define PLUGIN_PP(id, pp)\
((id##_pp_data *) pp->plugin_pp[id##_plugin->allocation_id])
#define CREATE_PLUGIN_PP_DATA(id, pp)\
(pp)->plugin_pp[id##_plugin->allocation_id] = (void *) (id##_plugin_new_pp_data(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 = *(World__Subjects__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)?(World__Subjects__get_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)?(World__Subjects__get_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 INSTANCE_COUNT(I, K)\
kind_instance_counts[(I)->allocation_id*max_kind_instance_count +\
Kinds__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 (object_is_a_backdrop(B))\
POSITIVE_KNOWLEDGE_LOOP(I, Data__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 (object_is_a_backdrop(B))\
POSITIVE_KNOWLEDGE_LOOP(I, Data__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 (Plugins__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 RED_NODE 1
#define BLACK_NODE 2
#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 LENGTH_OF_STORY_FILE_HEADER 0x40
#define BIBLIOGRAPHIC_TEXT_TRUNCATION 31
#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) && (t1->table_name_w1 >= 0) && (t2->table_name_w1 >= 0) &&\
(Text__compare_word_range(t2->table_name_w1, t2->table_name_w2,\
t1->table_name_w1, t1->table_name_w2)))
#define TABLE_NUMBERS_MATCH(t1, t2)\
((t1 != t2) && (t1->table_no_w1 >= 0) && (t2->table_no_w1 >= 0) &&\
(Text__compare_word_range(t2->table_no_w1, t2->table_no_w2,\
t1->table_no_w1, t1->table_no_w2)))
#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_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 NO_ADDED_REAL_CONSTANTS 2
#define MAX_ENODES_IN_EXPRESSION 100
#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 MAIN_TEXT_UO_ORIGIN 1
#define OPTIONS_FILE_UO_ORIGIN 2
#define EXTENSION_UO_ORIGIN 3
#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 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 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 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 MAX_DIVISION_FORMS 3
#define OTHERWISE_DIVISION 0
#define OTHERWISE_IF_DIVISION 1
#define CASE_DIVISION 2
#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 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 MAX_COMPLEX_SAY_DEPTH 32 /* and it would be terrible coding style to approach this */
#define DEFINED_POSITIVELY 1
#define DEFINED_NEGATIVELY -1
#define DEFINED_PHRASALLY 0
#define DEFINED_IN_SOME_WAY_NOT_YET_KNOWN -2
#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 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 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 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 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 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 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 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 THUMBNAIL_WIDTH 80
#define OWNED_BY_THIS_PROJECT 1
#define OWNED_BY_ANOTHER_PROJECT 2
#define OWNED_BY_SPECIFIC_PROJECT 3
#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 MAX_PLUGS 100
#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 = plugin_wording(NA);\
P->plugin_number = NA;\
P->set_name = plugin_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 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;\
}\
}
#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
#line 74 "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 267 "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 357 "inform7/Chapter 2/Memory.w"
typedef struct memblock_header {
int block_number;
struct memblock_header *next;
char *the_memory;
} memblock_header;
#line 446 "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 1157 "inform7/Chapter 2/Memory.w"
typedef struct general_pointer {
void *pointer_to_data;
int run_time_type_code;
} general_pointer;
#line 15 "inform7/Chapter 2/Single Integers.w"
typedef struct single_integer {
int the_integer;
} single_integer;
#line 227 "inform7/Chapter 2/Streams.w"
typedef struct 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 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;
} STREAM;
#line 29 "inform7/Chapter 2/Inform 6 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 1036 "inform7/Chapter 3/HTML Files.w"
typedef struct colour_translation {
char *chip_name;
char *html_colour;
} colour_translation;
#line 26 "inform7/Chapter 3/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 38 "inform7/Chapter 3/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 67 "inform7/Chapter 3/Index File Services.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 18 "inform7/Chapter 5/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 33 "inform7/Chapter 3/Lexicon Index.w"
typedef struct lexicon_entry {
int w1, w2; /* either the text of the entry, or |-1,-1|, 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 158 "inform7/Chapter 4/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 */
int range_quoted_w1, range_quoted_w2; /* for S and W only */
} problem_quotation;
#line 114 "inform7/Chapter 4/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 47 "inform7/Chapter 5/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 205 "inform7/Chapter 5/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 5/Read Source Text.w"
typedef struct source_file {
char filename[MAX_FILENAME_LENGTH];
char leafname[MAX_FILENAME_LENGTH];
int words_of_source; /* word count, omitting comments and verbatim matter */
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 38 "inform7/Chapter 5/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 meaning_list *start_list; /* meanings starting with this */
struct meaning_list *end_list; /* meanings ending with this */
struct meaning_list *middle_list; /* meanings with this inside but at neither end */
struct meaning_list *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 5/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 5/Tries and Inflections.w"
typedef struct match_avinue {
struct match_trie *the_trie;
struct match_avinue *next;
} match_avinue;
#line 25 "inform7/Chapter 5/Clusters.w"
typedef struct cluster {
struct individual_name *first_name;
MEMORY_MANAGEMENT
} cluster;
#line 30 "inform7/Chapter 5/Clusters.w"
typedef struct individual_name {
int word_ref1, word_ref2; /* 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 48 "inform7/Chapter 5/Clusters.w"
typedef struct plural_dictionary_entry {
int singular_w1, singular_w2; /* words of singular form */
int plural_form_w1, plural_form_w2; /* words of plural form */
MEMORY_MANAGEMENT
} plural_dictionary_entry;
#line 38 "inform7/Chapter 5/Natural Languages.w"
typedef struct natural_language {
char nl_bundle_path[MAX_FILENAME_LENGTH]; /* pathname of the bundle folder */
int word_ref1, word_ref2; /* instance name, e.g., "German language" */
struct instance *nl_instance; /* instance, e.g., "German language" */
int language_field_w1[MAX_LANGUAGE_FIELDS]; /* contents of the |about.txt| fields */
int language_field_w2[MAX_LANGUAGE_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 358 "inform7/Chapter 5/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 158 "inform7/Chapter 5/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 marked_internal; /* has, or will be given, an internal definition... */
int (*internal_definition)(int w1, int w2, 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, int w1, int w2);
int range_result_w1[MAX_RANGES_PER_PRODUCTION]; /* storage for word ranges matched */
int range_result_w2[MAX_RANGES_PER_PRODUCTION];
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 191 "inform7/Chapter 5/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 239 "inform7/Chapter 5/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 */
int sample_w1, sample_w2; /* ditto */
struct production *next_production; /* within its production list */
MEMORY_MANAGEMENT
} production;
#line 293 "inform7/Chapter 5/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 61 "inform7/Chapter 5/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 48 "inform7/Chapter 5/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 */
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 92 "inform7/Chapter 6/Parse Tree.w"
typedef struct parse_node {
int node_type; /* One of the list above */
int word_ref1, word_ref2; /* The text */
struct parse_node_annotation *annotations; /* Linked list: see below */
struct parse_node *down; /* Pointers to navigate the tree structure */
struct parse_node *next;
MEMORY_MANAGEMENT
} parse_node;
#line 106 "inform7/Chapter 6/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 38 "inform7/Chapter 6/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 6/Virtual Machines.w"
typedef struct VM_usage_note {
int word_ref1, word_ref2; /* 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 27 "inform7/Chapter 7/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 6/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 ..." */
int in_place_of_w1, in_place_of_w2; /* 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 170 "inform7/Chapter 6/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 180 "inform7/Chapter 6/Headings.w"
typedef struct contents_entry {
struct heading *heading_entered;
struct contents_entry *next;
MEMORY_MANAGEMENT
} contents_entry;
#line 30 "inform7/Chapter 6/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 requires_new_syntax;
int allow_run_on;
MEMORY_MANAGEMENT
} control_structure_phrase;
#line 79 "inform7/Chapter 6/Verify Parse Tree.w"
typedef struct parse_tree_node_type {
char *node_type_name; /* text of name of type, such as |"COMMAND_NT"| */
int min_children; /* minimum legal number of child nodes */
int max_children; /* maximum legal number of child nodes */
int node_weight; /* where higher weights sink to the bottom */
int required_parent_node_type; /* required node type of parent, or |-1| */
int allow_in_assertions; /* allow this on either side of an assertion? */
} parse_tree_node_type;
#line 163 "inform7/Chapter 7/Extension Files.w"
typedef struct extension_file {
struct extension_identifier ef_id; /* Texts of title and author with hash code */
int author_w1, author_w2; /* Author's name */
int name_w1, name_w2; /* Extension name */
int body_w1, body_w2; /* Body of source text supplied in extension, if any */
int body_text_unbroken; /* Does this contain text waiting to be sentence-broken? */
int doc_w1, doc_w2; /* Documentation supplied in extension, if any */
int VM_restriction_w1, VM_restriction_w2; /* 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 50 "inform7/Chapter 7/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 23 "inform7/Chapter 7/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 */
char *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 7/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 7/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 47 "inform7/Chapter 8/Traverse for Assertions.w"
typedef struct sentence_handler {
int 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 8/Make Assertions.w"
typedef struct matrix_entry {
int row_node_type;
int cases[ASSERTION_MATRIX_DIM];
} matrix_entry;
#line 39 "inform7/Chapter 8/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 parse_node copied; /* a deep copy of |what_to_make| */
struct generalisation *next; /* next in list of generalisations about kind */
MEMORY_MANAGEMENT
} generalisation;
#line 54 "inform7/Chapter 8/Assemblies.w"
typedef struct application {
struct inference_subject *generalisation_owner;
struct generalisation *latest_applied;
struct application *next;
} application;
#line 64 "inform7/Chapter 8/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" */
int named_after_w1, named_after_w2; /* text of the derived part, e.g. "nose" */
} assemblies_data;
#line 23 "inform7/Chapter 8/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 34 "inform7/Chapter 8/Implications.w"
typedef struct possession_marker {
int possessed; /* temporary use when checking implications about objects */
int possession_certainty; /* ditto */
} possession_marker;
#line 52 "inform7/Chapter 9/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 9/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 138 "inform7/Chapter 9/Binary Predicates.w"
typedef struct bp_term_details {
int word_ref1, word_ref2; /* "(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 205 "inform7/Chapter 9/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)$... */
int condition_defn_w1, condition_defn_w2; /* ...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$ */
int property_pending_w1, property_pending_w2; /* 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 9/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 28 "inform7/Chapter 9/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;
int vu_allow_unexpected_upper_case; /* for verbs like "to Hoover" */
MEMORY_MANAGEMENT
} verb_usage;
#line 59 "inform7/Chapter 9/Conjugation of Verbs.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 51 "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 14/I6 Schemas.w"
typedef struct i6_schema {
char prototype[MAX_I6_SCHEMA_LENGTH];
} i6_schema;
#line 84 "inform7/Chapter 9/Adjectives.w"
typedef struct adjective_meaning {
int index_w1, index_w2; /* 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 */
int definition_domain_w1, definition_domain_w2; /* domain to which defn applies */
struct inference_subject *domain_infs; /* what domain the defn applies to */
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 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 */
int word_ref1, word_ref2; /* 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 15/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 */
int prototype_w1, prototype_w2; /* where the prototype specification is */
int no_lp_tokens; /* number of tokens in specification */
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 {
int word_ref1, word_ref2; /* 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 67 "inform7/Chapter 10/Excerpt Meanings.w"
typedef struct excerpt_meaning {
unsigned int meaning_code; /* what kind of meaning: a single MC, not a bitmap */
unsigned int secondary_code; /* relevant only if the MC is |MISCELLANEOUS_MC| */
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 */
MEMORY_MANAGEMENT
} excerpt_meaning;
#line 41 "inform7/Chapter 11/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 11/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 11/Instances.w"
typedef struct instance_usage {
struct parse_node *where_instance_used;
struct instance_usage *next;
} instance_usage;
#line 123 "inform7/Chapter 12/Meaning Lists.w"
typedef struct meaning_list {
int expiry_time; /* an integer measured in creation "cycles": see below */
unsigned int production; /* a production code */
int word_ref1, word_ref2; /* word pair as usual */
struct excerpt_meaning *em; /* what this seems to mean... */
struct specification *type_spec; /* evaluation used in compaction */
struct general_pointer data_attached; /* certain productions have data attached */
struct meaning_list *next_alternative; /* fork to alternative meaning */
int score; /* a scoring system is used to choose most likely alternative */
struct meaning_list *sibling; /* tree of meanings of subordinate clauses */
struct meaning_list *child;
MEMORY_MANAGEMENT
} meaning_list;
#line 57 "inform7/Chapter 13/Terms.w"
typedef struct pcalc_term {
int variable; /* 0 to 25, or |-1| for "not a variable" */
struct specification *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 81 "inform7/Chapter 13/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 35 "inform7/Chapter 13/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" */
int calling_data; /* |CALLED_ATOM|: compacted form of a word range */
struct pcalc_prop *next; /* next atom in the list for this proposition */
} pcalc_prop;
#line 31 "inform7/Chapter 13/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 38 "inform7/Chapter 13/Type Check Propositions.w"
typedef struct tc_problem_kit {
int issue_error;
int ew1, ew2;
char *intention;
int log_to_I6_text;
int flag_problem;
} tc_problem_kit;
#line 27 "inform7/Chapter 14/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 35 "inform7/Chapter 14/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 15/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 104 "inform7/Chapter 15/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 66 "inform7/Chapter 15/Dimensions.w"
typedef struct dimensional_rules {
struct dimensional_rule *multiplications;
} dimensional_rules;
#line 177 "inform7/Chapter 15/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 192 "inform7/Chapter 15/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 36 "inform7/Chapter 15/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." */
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 specification */
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 69 "inform7/Chapter 15/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 92 "inform7/Chapter 15/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 102 "inform7/Chapter 15/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 113 "inform7/Chapter 15/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 176 "inform7/Chapter 15/Kind Interpreter.w"
typedef struct kind_command_definition {
char *text_of_command;
int opcode_number;
int operand_type;
} kind_command_definition;
#line 185 "inform7/Chapter 15/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 191 "inform7/Chapter 15/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 203 "inform7/Chapter 15/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 17 "inform7/Chapter 15/Describing 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 70 "inform7/Chapter 15/Dimensions.w"
typedef struct dimensional_rule {
int word_ref1, word_ref2;
struct kind *right;
struct kind *outcome;
struct dimensional_rule *next;
} dimensional_rule;
#line 313 "inform7/Chapter 15/Dimensions.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 119 "inform7/Chapter 16/Taxonomy of Specifications.w"
typedef struct taxon {
char source_name[32]; /* used in the debugging log: e.g. |CONDITION_FMY| */
int no_species_in_this_family; /* or 0 if not a family */
int family_of_which_this_is_species; /* or |UNKNOWN| if it isn't */
int species_flags; /* a bitmap of |*_SPCFLAG| flags, defined in "Specifications.w" */
} taxon;
#line 167 "inform7/Chapter 16/Taxonomy of Specifications.w"
typedef struct taxa_observations {
int legal_contexts;
struct specification *observations[NO_SPEC_CONTEXTS];
} taxa_observations;
#line 40 "inform7/Chapter 16/Specifications.w"
typedef struct specification {
int spec_packed_record; /* see below: a packed bitmap */
int family_and_species; /* |UNKNOWN|, or a family ID */
struct kind *associated_kind; /* |NULL|, or a kind of value */
int word_ref1, word_ref2; /* the text thus interpreted */
general_pointer which_structure; /* can point to any Inform structure */
struct time_period *condition_tense; /* |CONDITION_FMY|: records the tense */
struct pcalc_prop *proposition; /* |DESCRIPTION_SPC|, |TEST_PROPOSITION_SPC| */
struct description_docket *docket; /* |DESCRIPTION_SPC| */
struct specification *arguments[MAXIMUM_SPEC_ARGUMENTS];
} specification;
#line 74 "inform7/Chapter 16/Text to Specifications.w"
typedef struct expression_cache_entry {
int word_ref1, word_ref2; /* the word range whose parsing this is */
struct specification *cached_pe_spec; /* and the result (quite possibly |UNKNOWN|) */
} expression_cache_entry;
#line 68 "inform7/Chapter 16/Text to Specifications.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 19 "inform7/Chapter 16/VALUE Specifications.w"
typedef struct combinator {
struct specification *combination_item;
struct combinator *next;
MEMORY_MANAGEMENT
} combinator;
#line 17 "inform7/Chapter 16/CONDITION Specifications.w"
typedef struct description_docket {
struct quantifier *quant; /* such as "at most..." or "all" */
int quant_parameter; /* such as 3 in "at most 3" */
int no_adjectives_applied;
struct adjective_list_entry *adjectives_applied; /* see below */
struct kind *specific_kind; /* everything of this kind... */
struct instance *specific_object; /* ...or just this specific object */
int calling_w1, calling_w2; /* "black box" if "...(called the black box)" */
} description_docket;
#line 31 "inform7/Chapter 16/CONDITION Specifications.w"
typedef struct adjective_list_entry {
adjectival_phrase *ref_to;
int ref_positive; /* one of the above forms */
struct adjective_list_entry *next; /* in the list in this docket */
} adjective_list_entry;
#line 15 "inform7/Chapter 16/Type Checking.w"
typedef struct inv_token_problem_token {
int word_ref1, word_ref2;
struct specification *as_parsed;
int already_described;
MEMORY_MANAGEMENT
} inv_token_problem_token;
#line 71 "inform7/Chapter 16/Invocations.w"
typedef struct invocation_list {
struct invocation_list_entry *list_head;
struct invocation_list_entry *list_tail; /* storing this makes Inform 5\% faster on large sources */
} invocation_list;
#line 76 "inform7/Chapter 16/Invocations.w"
typedef struct invocation_list_entry {
struct invocation *listed_inv;
struct invocation_list_entry *next;
} invocation_list_entry;
#line 84 "inform7/Chapter 16/Invocations.w"
typedef struct invocation {
int inv_packed_record; /* see below: a packed bitmap */
int invocation_w1, invocation_w2; /* text which this invocation interprets */
struct phrase *phrase_invoked; /* the phrase believed to be invoked... */
struct verb_conjugation *say_verb; /* ...or the verb to be conjugated by "say" */
struct verb_conjugation *modal_verb; /* relevant only for that: e.g., "might" */
int say_verb_negated; /* relevant only for that */
struct adjectival_phrase *say_adjective; /* ...or the adjective to be agreed with by "say" */
struct invocation_options *phrase_options_invoked; /* details of any options used */
int ssp_segment_count; /* number of subsequent complex-say phrases in stream */
int ssp_closing_segment_wn; /* identifier for the last of these, or |-1| */
struct invocation_token_list *tokens_invoked; /* linked list of these */
struct kind_variable_declaration *kind_variable_declarations; /* and of these */
struct kind *kind_resulting; /* what if anything is returned */
} invocation;
#line 130 "inform7/Chapter 16/Invocations.w"
typedef struct invocation_options {
int options; /* bitmap of any phrase options appended */
int options_invoked_w1, options_invoked_w2; /* text of any phrase options appended */
} invocation_options;
#line 146 "inform7/Chapter 16/Invocations.w"
typedef struct invocation_token_list {
struct specification *token_to_be_parsed_against; /* how we will find it */
struct specification *token_as_parsed; /* what we find */
struct specification *token_check_to_do; /* what we need */
struct kind *kind_of_new_variable; /* or null if none is to be created here */
struct invocation_token_list *next;
} invocation_token_list;
#line 34 "inform7/Chapter 17/Properties.w"
typedef struct property {
int word_ref1, word_ref2; /* 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 17/Measurement Adjectives.w"
typedef struct measurement_definition {
struct parse_node *measurement_node; /* where the actual definition is */
int headword_wn; /* word number of the adjective being defined (must be single word) */
struct adjective_meaning *headword_as_adjective; /* which adjective meaning */
int superlative_wn; /* word number of its superlative form */
struct property *prop; /* the property being compared, if any */
int pname_w1, pname_w2; /* 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? */
int region_threshold_w1, region_threshold_w2; /* text of threshold value */
int property_schema_written; /* I6 schema for testing written yet? */
MEMORY_MANAGEMENT
} measurement_definition;
#line 24 "inform7/Chapter 17/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 37 "inform7/Chapter 18/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 18/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 18/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 specification *spec_ref1; /* used by dynamic relations between non-subjects */
struct specification *spec_ref2;
struct property *inferred_property; /* property referred to, if any */
struct specification *inferred_property_value; /* and its value, if any */
struct inference *next; /* next in list of inferences on same subject */
} inference;
#line 18 "inform7/Chapter 18/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 19/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 19/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 22 "inform7/Chapter 19/Spatial Geometry.w"
typedef struct vector {
int x, y, z;
} vector;
#line 40 "inform7/Chapter 19/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 19/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 29 "inform7/Chapter 19/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 50 "inform7/Chapter 19/Spatial Geometry.w"
typedef struct cuboid {
int population;
struct vector corner0;
struct vector corner1;
} cuboid;
#line 72 "inform7/Chapter 19/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 19/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 19/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 30 "inform7/Chapter 19/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 37 "inform7/Chapter 19/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 */
int end_names_w1[MAX_SCENE_ENDS]; /* for ends 2, 3, ...: e.g. "badly" */
int end_names_w2[MAX_SCENE_ENDS];
struct rulebook *end_rulebook[MAX_SCENE_ENDS]; /* rules to apply then */
struct specification *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 52 "inform7/Chapter 20/Text Literals.w"
typedef struct literal_text {
int word_ref1; /* 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 20/Text Substitutions.w"
typedef struct text_substitution {
int word_ref1, word_ref2; /* text when expanded just prior to compilation */
int wn; /* position of unexpanded text in the source of quoted text */
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 20/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 19 "inform7/Chapter 20/Nonlocal Variables.w"
typedef struct nonlocal_variable {
int word_ref1, word_ref2; /* text of the name */
struct parse_node *nlv_created_at; /* sentence creating the variable */
int var_documentation_symbol_wn; /* 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 */
MEMORY_MANAGEMENT
} nonlocal_variable;
#line 48 "inform7/Chapter 20/Release Instructions.w"
typedef struct auxiliary_file {
char *leafname_in_materials_folder; /* e.g., "Collegio.pdf" */
char *brief_description; /* e.g., "Collegio Magazine" */
char *foldername_in_release_folder; /* e.g., "hidden_files" */
int from_payload;
MEMORY_MANAGEMENT
} auxiliary_file;
#line 25 "inform7/Chapter 20/List Constants.w"
typedef struct literal_list {
int word_ref1, word_ref2; /* 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 20/List Constants.w"
typedef struct llist_entry {
struct specification *llist_entry_value;
struct llist_entry *next_llist_entry;
MEMORY_MANAGEMENT
} llist_entry;
#line 28 "inform7/Chapter 20/Table Columns.w"
typedef struct table_column {
int word_ref1, word_ref2; /* 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 20/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 */
int kind_declaration_w1, kind_declaration_w2; /* 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 20/Tables.w"
typedef struct table {
int table_no_w1, table_no_w2; /* the table number (if any) */
int table_name_w1, table_name_w2; /* 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) */
int blank_rows_for_each_w1, blank_rows_for_each_w2; /* add one blank for each instance */
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 */
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 51 "inform7/Chapter 20/Tables.w"
typedef struct table_contribution {
struct parse_node *source_table;
struct table_contribution *next;
} table_contribution;
#line 22 "inform7/Chapter 21/Equations.w"
typedef struct equation {
int word_ref1, word_ref2; /* the text of the actual equation */
int equation_no_w1, equation_no_w2; /* the equation number (if any) */
int equation_name_w1, equation_name_w2; /* the equation name (if any) */
int where_w1, where_w2; /* declaration of symbols */
int usage_w1, usage_w2; /* 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 21/Equations.w"
typedef struct equation_symbol {
char variable_name[16]; /* C string form of name of the var (not done with words) */
int variable_wn; /* word number of this name */
struct kind *var_kind; /* if a variable -- must be quasinumerical */
struct phrase *function_notated; /* if a phrase QN to QN */
struct specification *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 */
MEMORY_MANAGEMENT
} equation_symbol;
#line 110 "inform7/Chapter 21/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 specification *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? */
MEMORY_MANAGEMENT
} equation_node;
#line 26 "inform7/Chapter 21/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 52 "inform7/Chapter 21/Inform 6 Inclusions.w"
typedef struct use_option {
int word_ref1, word_ref2; /* 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 78 "inform7/Chapter 21/Inform 6 Inclusions.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 21/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 69 "inform7/Chapter 22/Phrase Type Data.w"
typedef struct phrase_token {
int word_ref1, word_ref2; /* name */
struct specification *to_match; /* what we expect to find here */
struct kind *token_kind;
int name_of_a_kind; /* |TRUE| if a name of a kind of value is the value */
} phrase_token;
#line 102 "inform7/Chapter 22/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 137 "inform7/Chapter 22/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 48 "inform7/Chapter 22/Phrase Type Data.w"
typedef struct ph_type_data {
int register_w1, register_w2; /* 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 22 "inform7/Chapter 22/Phrase Usage.w"
typedef struct ph_usage_data {
int full_preamble_w1, full_preamble_w2; /* 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;
int explicit_name_w1, explicit_name_w2; /* 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()| */
int explicit_name_for_inverse; /* word number for explicit inverse function name */
int whenwhile_w1, whenwhile_w2; /* when/while for action/activity rulebooks */
int rule_preamble_w1, rule_preamble_w2;
int rule_parameter_w1, rule_parameter_w2; /* text of object or action parameter */
struct specification *during_scene_spec; /* what scene is currently under way */
int event_name_w1, event_name_w2;
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 35 "inform7/Chapter 24/Chronology.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 31 "inform7/Chapter 24/Action Patterns.w"
typedef struct action_pattern {
int word_ref1, word_ref2; /* text giving rise to this AP */
struct named_action_pattern *named; /* give a named action pattern... */
struct action_name_list *action; /* ...or give an ANL list (not both) */
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 specification *actor_spec;
struct specification *noun_spec;
int noun_any;
struct specification *second_spec;
int second_any;
struct specification *presence_spec; /* in the presence of... */
struct specification *room_spec; /* in... */
int room_any;
struct specification *when; /* when... (any condition here) */
struct specification *from_spec; /* for the "going" action only */
struct specification *to_spec; /* ditto */
struct specification *by_spec; /* ditto */
struct specification *through_spec; /* ditto */
struct specification *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 specification *parameter_spec; /* alternatively, just this */
struct kind *parameter_kind; /* of this expected kind */
int AP_parity; /* |+1| if meant positively, |-1| if negatively */
int valid; /* recording success or failure in parsing to an AP */
int has_substance_other_than_wh; /* not for instance "when X is 2" */
struct action_pattern *next; /* for forming APs into linked lists */
} action_pattern;
#line 28 "inform7/Chapter 22/Phrase Runtime Context Data.w"
typedef struct ph_runtime_context_data {
int activity_context_w1, activity_context_w2; /* happens only while any activities go on? */
struct parse_node *activity_where; /* and who says? */
struct activity_list *avl;
struct specification *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 22/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 */
int it_pseudonym_w1, it_pseudonym_w2; /* a further variation on the same variable */
} locals_slate;
#line 23 "inform7/Chapter 22/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 22/Phrase Options.w"
typedef struct ph_options_data {
struct phrase_option *options_permitted[MAX_OPTIONS_PER_PHRASE]; /* see below */
int no_options_permitted;
int options_w1, options_w2; /* the text declaring the whole set of options */
int multiple_options_permitted; /* can be combined, or mutually exclusive? */
} ph_options_data;
#line 69 "inform7/Chapter 22/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| */
int ph_documentation_symbol_wn; /* 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 22/Phrase Options.w"
typedef struct phrase_option {
int word_ref1, word_ref2; /* text of name */
} phrase_option;
#line 52 "inform7/Chapter 22/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? */
int varname_w1, varname_w2; /* name of local variable */
int name_hash; /* hash code for this name */
int block_scope; /* scope of a local - block depth */
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 36 "inform7/Chapter 22/Phrase Blocks.w"
typedef struct phrase_block {
struct phrase *from_phrase; /* e.g., "if" or "while" */
struct parse_node *block_location; /* where block begins */
struct kind *switch_kind; /* for a switch statement */
struct STREAM *tail_stream; /* code to add when the block closes */
int division_count[MAX_DIVISION_FORMS]; /* number of block divisions of different sorts */
int label_following; /* or -1 if none is used */
} phrase_block;
#line 31 "inform7/Chapter 22/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 22/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 22/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 19 "inform7/Chapter 22/Compile Invocations.w"
typedef struct invocation_group {
struct invocation_list *invl_in_question;
struct invocation *first_inv; /* first invocation in the group */
int first_pos; /* index in list, counting from 0 */
struct invocation *last_inv; /* last invocation in the group (inclusive!) */
int last_pos; /* and its index */
struct invocation *first_in_next_group; /* or null if this is the last */
int say_like; /* a collection of say phrases or their equivalent */
} invocation_group;
#line 32 "inform7/Chapter 22/Compile Invocations.w"
typedef struct tokens_packet {
int tokens_count; /* number of arguments to phrase */
struct specification *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 17 "inform7/Chapter 22/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 20 "inform7/Chapter 22/Phrases as Values.w"
typedef struct constant_phrase {
int word_ref1, word_ref2;
struct phrase *phrase_meant; /* if known at this point */
struct kind *cphr_kind; /* ditto */
int cphr_form_w1, cphr_form_w2; /* text of associated preamble */
MEMORY_MANAGEMENT
} constant_phrase;
#line 30 "inform7/Chapter 22/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 */
int condition_w1, condition_w2; /* text of condition to match, if |+1| or |-1| */
int domain_calling_w1, domain_calling_w2; /* what if anything the term is called */
struct adjective_meaning *am_of_def; /* which adjective meaning */
MEMORY_MANAGEMENT
} definition;
#line 26 "inform7/Chapter 22/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 46 "inform7/Chapter 23/Rules.w"
typedef struct rule {
int word_ref1, word_ref2; /* name of the rule being booked */
int explicitly_named; /* was this rule explicitly named when created? */
int italicised_text_w1, italicised_text_w2; /* 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;
int lettered_responses_value_wn[26];
MEMORY_MANAGEMENT
} rule;
#line 83 "inform7/Chapter 23/Rules.w"
typedef struct applicability_condition {
int word_ref1, word_ref2; /* 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 23/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 23/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 23/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 51 "inform7/Chapter 23/Rulebooks.w"
typedef struct rulebook {
int word_ref1, word_ref2; /* name in source text */
int alt_word_ref1, alt_word_ref2; /* 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 78 "inform7/Chapter 23/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 94 "inform7/Chapter 23/Rulebooks.w"
typedef struct placement_affecting {
struct parse_node *placement_sentence;
struct placement_affecting *next;
MEMORY_MANAGEMENT
} placement_affecting;
#line 73 "inform7/Chapter 23/Focus and Outcome.w"
typedef struct named_rulebook_outcome {
int word_ref1, word_ref2; /* Name in source text */
MEMORY_MANAGEMENT
} named_rulebook_outcome;
#line 78 "inform7/Chapter 23/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 23/Stacked Variables.w"
typedef struct stacked_variable {
int word_ref1, word_ref2; /* 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) */
int mw1, mw2; /* matching text (relevant for action variables only) */
MEMORY_MANAGEMENT
} stacked_variable;
#line 26 "inform7/Chapter 23/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 23/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 23/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 49 "inform7/Chapter 24/Chronology.w"
typedef struct past_tense_condition_record {
struct specification *condition; /* condition to be evaluated */
struct parse_node *where_ptc_tested; /* sentence in which condition is found */
MEMORY_MANAGEMENT
} past_tense_condition_record;
#line 55 "inform7/Chapter 24/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 39 "inform7/Chapter 24/Actions.w"
typedef struct action_name {
int word_ref1, word_ref2; /* such as "drop" or "take" */
int past_word_ref1, past_word_ref2; /* 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 16 "inform7/Chapter 24/Action Name Lists.w"
typedef struct action_name_list {
struct action_name *action_listed; /* the action in this ANL list entry */
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;
int parameter_w1[2], parameter_w2[2];
int in_w1, in_w2;
int abbreviation_level; /* number of words missing */
int anyone_specified;
int delete_this_link; /* used temporarily during parsing */
} action_name_list;
#line 69 "inform7/Chapter 24/Action Patterns.w"
typedef struct ap_optional_clause {
struct stacked_variable *stv_to_match;
struct specification *clause_spec;
int allow_region_as_room;
struct ap_optional_clause *next;
MEMORY_MANAGEMENT
} ap_optional_clause;
#line 14 "inform7/Chapter 24/Looping Over Scope.w"
typedef struct loop_over_scope {
struct specification *what_to_find;
MEMORY_MANAGEMENT
} loop_over_scope;
#line 15 "inform7/Chapter 24/Named Action Patterns.w"
typedef struct named_action_pattern {
struct action_pattern *first; /* list of APs defining this NAP */
int word_ref1, word_ref2; /* 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 24/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 23 "inform7/Chapter 24/Activities.w"
typedef struct activity {
int word_ref1, word_ref2; /* 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 */
int av_documentation_symbol_wn; /* 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 24/Activities.w"
typedef struct activity_list {
struct activity *activity; /* what activity */
struct specification *acting_on; /* the parameter */
struct specification *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 24/Activities.w"
typedef struct activity_crossref {
struct phrase *rule_dependent;
struct activity_crossref *next;
} activity_crossref;
#line 18 "inform7/Chapter 25/Traverse for Grammar.w"
typedef struct cached_understanding {
int word_ref1, word_ref2; /* 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 25/Traverse for Grammar.w"
typedef struct understanding_item {
int quoted_text_w1, quoted_text_w2;
struct property *quoted_property;
struct understanding_item *next;
} understanding_item;
#line 33 "inform7/Chapter 25/Traverse for Grammar.w"
typedef struct understanding_reference {
int word_ref1, word_ref2;
int gv_result;
int mword;
int pluralised_reference;
int reversed_reference;
action_name *an_reference;
specification *spec_reference;
struct understanding_reference *next;
} understanding_reference;
#line 34 "inform7/Chapter 25/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 42 "inform7/Chapter 25/Grammar Properties.w"
typedef struct parsing_pp_data {
int visibility_level_in_parser; /* if so, does the run-time I6 parser recognise it? */
int visibility_condition_w1, visibility_condition_w2; /* (at least if...?) */
struct parse_node *visibility_sentence; /* where this is specified */
MEMORY_MANAGEMENT
} parsing_pp_data;
#line 14 "inform7/Chapter 25/Grammar Types.w"
typedef struct grammar_type {
int no_resulting_values; /* number of resulting values: 0, 1 or 2; or |-1| */
struct specification *first_type; /* and their types */
struct specification *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 25/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 */
int command_wn; /* |GV_IS_COMMAND|: word number at which command found */
int aliased_command_wn[MAX_ALIASED_COMMANDS]; /* ...and other commands synonymous */
int no_aliased_commands; /* ...and how many of them there are */
int word_ref1, word_ref2; /* |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 25/Grammar Verbs.w"
typedef struct reserved_command_verb {
char reserved_text[32];
MEMORY_MANAGEMENT
} reserved_command_verb;
#line 36 "inform7/Chapter 25/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 */
int understand_when_w1, understand_when_w2; /* only 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? */
int mistake_response_wn; /* if so, reply with the text at this word number */
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 68 "inform7/Chapter 25/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 25/Noun Filter Tokens.w"
typedef struct noun_filter_token {
struct specification *the_filter;
struct parse_node *nft_created_at;
int global_scope_flag;
int parse_using_gpr;
int nft_compiled;
char nft_routine_name[32];
MEMORY_MANAGEMENT
} noun_filter_token;
#line 28 "inform7/Chapter 25/Test Scripts.w"
typedef struct test_scenario {
int name_wn; /* word number of single word identifying the test */
char text_of_script[MAX_LENGTH_OF_SCRIPT];
int commands_wn; /* word number of quoted text of command sequence */
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 42 "inform7/Chapter 25/Test Scripts.w"
typedef struct internal_test_case {
int itc_code; /* one of the above |*_INTT| values */
int word_ref1, word_ref2; /* text supplying the case */
struct parse_node *itc_defined_at;
MEMORY_MANAGEMENT
} internal_test_case;
#line 19 "inform7/Chapter 26/Figures.w"
typedef struct blorb_figure {
int word_ref1, word_ref2; /* text of figure name */
char path_to_figure[MAX_FILENAME_LENGTH]; /* relative to the Resources folder */
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 26/Sound Effects.w"
typedef struct blorb_sound {
int word_ref1, word_ref2; /* text of sound name */
char path_to_sound[MAX_FILENAME_LENGTH]; /* 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 26/External Files.w"
typedef struct external_file {
int word_ref1, word_ref2; /* 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 27/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 */
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 20 "inform7/Chapter 27/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 47 "inform7/Chapter 27/Plugins.w"
typedef struct plugin_call {
void *routine;
struct plugin_call *next;
} plugin_call;
#line 118 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Windows_specific_isdigit(int c) ;
#line 175 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__platform_specific_mkdir(char *path_to_folder) ;
#line 187 "inform7/Chapter 1/Platform-Specific Definitions.w"
void * Platform__platform_specific_opendir(char *path_to_folder) ;
#line 192 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__platform_specific_readdir(void *folder, char *path_to_folder, char *leafname) ;
#line 211 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__platform_specific_closedir(void *folder) ;
#line 229 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__platform_specific_mkdir(char *path_to_folder) ;
#line 241 "inform7/Chapter 1/Platform-Specific Definitions.w"
void * Platform__platform_specific_opendir(char *path_to_folder) ;
#line 246 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__platform_specific_readdir(void *folder, char *path_to_folder, char *leafname) ;
#line 266 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__platform_specific_closedir(void *folder) ;
#line 298 "inform7/Chapter 1/Platform-Specific Definitions.w"
FILE * Platform__iso_fopen(char *pathname, char *usage) ;
#line 304 "inform7/Chapter 1/Platform-Specific Definitions.w"
FILE * Platform__iso_fopen_caseless(char *pathname, char *usage) ;
#line 314 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__transcode_ISO_string_to_locale(char *from, char *to) ;
#line 320 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__transcode_ISO_string_to_locale(char *from, char *to) ;
#line 340 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__truncated_locale_fgets(FILE *F, char *buffer, int limit) ;
#line 346 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__truncated_locale_fgets(FILE *F, char *buffer, int limit) ;
#line 367 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__truncated_locale_arg(char *arg, char *buffer, int limit) ;
#line 373 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__truncated_locale_arg(char *arg, char *buffer, int limit) ;
#line 390 "inform7/Chapter 1/Platform-Specific Definitions.w"
char Platform__tolower(char c) ;
#line 393 "inform7/Chapter 1/Platform-Specific Definitions.w"
char Platform__toupper(char c) ;
#line 396 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__isalpha(char c) ;
#line 399 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__isdigit(char c) ;
#line 402 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__strlen(const char *p) ;
#line 287 "inform7/Chapter 2/Memory.w"
void Memory__start(void) ;
#line 372 "inform7/Chapter 2/Memory.w"
void allocate_another_block(void) ;
#line 423 "inform7/Chapter 2/Memory.w"
void Memory__free_memory(void) ;
#line 470 "inform7/Chapter 2/Memory.w"
void check_memory_integrity(void) ;
#line 487 "inform7/Chapter 2/Memory.w"
void debug_memory_frames(int from, int to) ;
#line 506 "inform7/Chapter 2/Memory.w"
void * allocate_mem(int mem_type, int extent) ;
#line 917 "inform7/Chapter 2/Memory.w"
void * Memory__I7_calloc(int how_many, int size_in_bytes, int reason) ;
#line 920 "inform7/Chapter 2/Memory.w"
void * Memory__I7_malloc(int size_in_bytes, int reason) ;
#line 927 "inform7/Chapter 2/Memory.w"
void * I7_alloc(int N, int S, int R) ;
#line 984 "inform7/Chapter 2/Memory.w"
void Memory__I7_free(void *pointer, int R) ;
#line 1006 "inform7/Chapter 2/Memory.w"
void I7_free_all_remaining(void) ;
#line 1020 "inform7/Chapter 2/Memory.w"
int log_I7_alloc_usage(int total) ;
#line 1039 "inform7/Chapter 2/Memory.w"
void Memory__log_statistics(void) ;
#line 1119 "inform7/Chapter 2/Memory.w"
int compare_usage_entries(const void *ent1, const void *ent2) ;
#line 1129 "inform7/Chapter 2/Memory.w"
int memory_proportion(int bytes, int total) ;
#line 1162 "inform7/Chapter 2/Memory.w"
general_pointer store_gp_null(void) ;
#line 1168 "inform7/Chapter 2/Memory.w"
int test_gp_null(general_pointer gp) ;
#line 24 "inform7/Chapter 2/Single Integers.w"
int Memory__SingleIntegers__get(single_integer *sint) ;
#line 29 "inform7/Chapter 2/Single Integers.w"
single_integer * Memory__SingleIntegers__new(int t) ;
#line 268 "inform7/Chapter 2/Streams.w"
void stream_initialise(STREAM *stream) ;
#line 289 "inform7/Chapter 2/Streams.w"
STREAM * stream_get_stdout(void) ;
#line 301 "inform7/Chapter 2/Streams.w"
STREAM * stream_get_stderr(void) ;
#line 314 "inform7/Chapter 2/Streams.w"
int stream_open_to_file(STREAM *stream, char *filename, int encoding) ;
#line 328 "inform7/Chapter 2/Streams.w"
int stream_open_to_file_append(STREAM *stream, char *filename, int encoding) ;
#line 345 "inform7/Chapter 2/Streams.w"
int stream_open_to_memory(STREAM *stream, int capacity) ;
#line 363 "inform7/Chapter 2/Streams.w"
STREAM stream_new_buffer(int capacity, char *at) ;
#line 380 "inform7/Chapter 2/Streams.w"
void stream_flush(STREAM *stream) ;
#line 388 "inform7/Chapter 2/Streams.w"
void stream_close(STREAM *stream) ;
#line 436 "inform7/Chapter 2/Streams.w"
void stream_printf(STREAM *stream, char *fmt, ...) ;
#line 514 "inform7/Chapter 2/Streams.w"
void stream_putc(int c_int, STREAM *stream) ;
#line 629 "inform7/Chapter 2/Streams.w"
void stream_literal(STREAM *stream, char *p) ;
#line 644 "inform7/Chapter 2/Streams.w"
void stream_indent(STREAM *stream) ;
#line 649 "inform7/Chapter 2/Streams.w"
void stream_outdent(STREAM *stream) ;
#line 656 "inform7/Chapter 2/Streams.w"
void set_stream_indentation(STREAM *stream, int N) ;
#line 668 "inform7/Chapter 2/Streams.w"
int stream_get_position(STREAM *stream) ;
#line 682 "inform7/Chapter 2/Streams.w"
int stream_latest(STREAM *stream) ;
#line 701 "inform7/Chapter 2/Streams.w"
void stream_set_position(STREAM *stream, int position) ;
#line 728 "inform7/Chapter 2/Streams.w"
char * stream_get_text(STREAM *stream) ;
#line 738 "inform7/Chapter 2/Streams.w"
void stream_copy(STREAM *to, STREAM *from) ;
#line 145 "inform7/Chapter 2/Filenames.w"
void Files__Filenames__make_pathname_of_extensions(void) ;
#line 174 "inform7/Chapter 2/Filenames.w"
void Files__Filenames__make_pathname_of_materials_folder(void) ;
#line 196 "inform7/Chapter 2/Filenames.w"
char * Files__Filenames__top_level(char *leafname) ;
#line 211 "inform7/Chapter 2/Filenames.w"
char * Files__Filenames__build(char *leafname) ;
#line 229 "inform7/Chapter 2/Filenames.w"
char * source_filename(char *leafname) ;
#line 236 "inform7/Chapter 2/Filenames.w"
char * Files__Filenames__source_filename_relative_to_bundle(char *leafname) ;
#line 252 "inform7/Chapter 2/Filenames.w"
char * Files__Filenames__index(char *leafname, int sub) ;
#line 292 "inform7/Chapter 2/Filenames.w"
int Files__Folders__verify_library_folder(char *p1, char *p2, char *p3, char *new) ;
#line 319 "inform7/Chapter 2/Filenames.w"
int Files__Folders__verify_installed_extensions_tree(void) ;
#line 342 "inform7/Chapter 2/Filenames.w"
int Files__Folders__write_contents_to_file(char *pathname, char *writeto) ;
#line 360 "inform7/Chapter 2/Filenames.w"
int Files__Folders__write_contents_to_stream(OUTPUT_STREAM, char *pathname) ;
#line 380 "inform7/Chapter 2/Filenames.w"
int Files__truncated_iso_fgets(FILE *F, char *buffer, int limit) ;
#line 58 "inform7/Chapter 2/Case-Insensitive Filenames.w"
FILE * Files__case_insensitive_fopen(const char *path, const char *mode) ;
#line 231 "inform7/Chapter 2/Case-Insensitive Filenames.w"
int count_matches_within_directory(void *vd, char *name, char *last_match) ;
#line 254 "inform7/Chapter 2/Case-Insensitive Filenames.w"
FILE * Files__case_insensitive_fopen(const char *path, const char *mode) ;
#line 29 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compose_identifier(char *ledger, char nature_character, int id_number, int w1, int w2) ;
#line 50 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__purify_identifier(char *identifier) ;
#line 117 "inform7/Chapter 2/Make Inform 6 Names.w"
void translates_into_I6_as(parse_node *pn) ;
#line 199 "inform7/Chapter 2/Make Inform 6 Names.w"
void add_extra_responses_to_rule(parse_node *p, rule *R) ;
#line 250 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_dictionary_word(OUTPUT_STREAM, char *p, int pluralise) ;
#line 298 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_string(OUTPUT_STREAM, char *p, int options) ;
#line 382 "inform7/Chapter 2/Make Inform 6 Names.w"
int isalpha_accented(int letter) ;
#line 391 "inform7/Chapter 2/Make Inform 6 Names.w"
int Formats__Inform6__expand_unisub(OUTPUT_STREAM, char *p, int i) ;
#line 414 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_text(OUTPUT_STREAM, int w1, int w2, int opts, int raw) ;
#line 427 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_as_comment(OUTPUT_STREAM, int w1, int w2) ;
#line 431 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_text_simply(OUTPUT_STREAM, int w1, int w2) ;
#line 438 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_divider_comment(OUTPUT_STREAM) ;
#line 42 "inform7/Chapter 2/Inform 6 Labels.w"
label_namespace * lns_new(char *name) ;
#line 64 "inform7/Chapter 2/Inform 6 Labels.w"
label_namespace * lns_by_prefix(char *name) ;
#line 72 "inform7/Chapter 2/Inform 6 Labels.w"
label_namespace * lns_read_or_create(char *name) ;
#line 83 "inform7/Chapter 2/Inform 6 Labels.w"
int Formats__Inform6__Labels__Counters__read(char *namespace, int advance_flag) ;
#line 94 "inform7/Chapter 2/Inform 6 Labels.w"
void Formats__Inform6__Labels__write(OUTPUT_STREAM, char *namespace) ;
#line 108 "inform7/Chapter 2/Inform 6 Labels.w"
void Formats__Inform6__Labels__Counters__allocate(char *namespace, int multiplier) ;
#line 113 "inform7/Chapter 2/Inform 6 Labels.w"
void Formats__Inform6__Labels__Counters__compile_allocated_storage(OUTPUT_STREAM) ;
#line 15 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__read_int8(FILE *binary_file, unsigned int *result) ;
#line 23 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__read_int16(FILE *binary_file, unsigned int *result) ;
#line 34 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__read_int32(FILE *binary_file, unsigned int *result) ;
#line 49 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__read_int64(FILE *binary_file, unsigned long long *result) ;
#line 78 "inform7/Chapter 2/Image Dimensions.w"
void Files__Formats__swap_bytes32(unsigned int *value) ;
#line 86 "inform7/Chapter 2/Image Dimensions.w"
void Files__Formats__swap_bytes64(unsigned long long *value) ;
#line 104 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__read_variable_length_integer(FILE *binary_file, unsigned int *result) ;
#line 121 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__read_float80(FILE *binary_file, unsigned int *result) ;
#line 146 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__read_string(FILE *binary_file, char *string, unsigned int length) ;
#line 173 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__JPEG__get_dimensions(FILE *JPEG_file, unsigned int *width, unsigned int *height) ;
#line 226 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__PNG__get_dimensions(FILE *PNG_file, unsigned int *width, unsigned int *height) ;
#line 15 "inform7/Chapter 2/Sound Durations.w"
int Files__Formats__AIFF__get_duration(FILE *pFile, unsigned int *pDuration, unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) ;
#line 62 "inform7/Chapter 2/Sound Durations.w"
int Files__Formats__OggVorbis__get_duration(FILE *pFile, unsigned int *pDuration, unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) ;
#line 184 "inform7/Chapter 2/Sound Durations.w"
int Files__Formats__Midi__get_information(FILE *pFile, unsigned int *pType, unsigned int *pNumTracks) ;
#line 104 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__html_source_link(OUTPUT_STREAM, source_location sl, int nonbreaking_space) ;
#line 125 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__html_icon_with_tooltip(OUTPUT_STREAM, char *icon_name, char *tip, char *tip2) ;
#line 182 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__html_outcome_image(OUTPUT_STREAM, char *image, char *verdict) ;
#line 233 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__outcome_image_tail(OUTPUT_STREAM) ;
#line 250 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__html_header(OUTPUT_STREAM, char *title, char *thumbnail, char *caption) ;
#line 420 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__html_header_complete(OUTPUT_STREAM, char *title, char *thumbnail) ;
#line 429 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__html_footer(OUTPUT_STREAM) ;
#line 437 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__open_para(OUTPUT_STREAM, int depth, char *class) ;
#line 448 "inform7/Chapter 3/HTML Files.w"
void test_html_paragraphs(void) ;
#line 498 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__html_char_out(OUTPUT_STREAM, char c) ;
#line 546 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__begin_plain_html_table(OUTPUT_STREAM) ;
#line 550 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__begin_wide_html_table(OUTPUT_STREAM) ;
#line 559 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__begin_html_table(OUTPUT_STREAM, char *colour, int full_width, int border, int cellspacing, int cellpadding, int height, int width) ;
#line 572 "inform7/Chapter 3/HTML Files.w"
void Formats__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 583 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__first_html_column(OUTPUT_STREAM, int width) ;
#line 588 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__first_html_column_nowrap(OUTPUT_STREAM, int width, char *colour) ;
#line 594 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__first_html_column_spaced(OUTPUT_STREAM, int width) ;
#line 599 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__first_html_column_coloured(OUTPUT_STREAM, int width, char *col, int cs) ;
#line 607 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__next_html_column(OUTPUT_STREAM, int width) ;
#line 613 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__next_html_column_centred(OUTPUT_STREAM, int width) ;
#line 619 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__next_html_column_spanning(OUTPUT_STREAM, int width, int sp) ;
#line 625 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__next_html_column_nowrap(OUTPUT_STREAM, int width) ;
#line 631 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__next_html_column_spaced(OUTPUT_STREAM, int width) ;
#line 637 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__next_html_column_nw(OUTPUT_STREAM, int width) ;
#line 643 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__next_html_column_w(OUTPUT_STREAM, int width) ;
#line 648 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__next_html_column_right_justified(OUTPUT_STREAM, int width) ;
#line 653 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__end_html_row(OUTPUT_STREAM) ;
#line 656 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__end_html_table(OUTPUT_STREAM) ;
#line 667 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__open_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) ;
#line 680 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__close_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) ;
#line 691 "inform7/Chapter 3/HTML Files.w"
void box_corner(OUTPUT_STREAM, char *html_colour, char *corner) ;
#line 702 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__write_xml_safe_text(OUTPUT_STREAM, char *txt) ;
#line 726 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__compile_bibliographic_text(OUTPUT_STREAM, char *p) ;
#line 910 "inform7/Chapter 3/HTML Files.w"
int Formats__HTML__iso_remove_accents(int charcode) ;
#line 945 "inform7/Chapter 3/HTML Files.w"
int Formats__HTML__combining_accent(int accent, int letter) ;
#line 998 "inform7/Chapter 3/HTML Files.w"
int Formats__HTML__without_accent(int letter) ;
#line 1026 "inform7/Chapter 3/HTML Files.w"
int is_babel_whitespace(char c) ;
#line 1192 "inform7/Chapter 3/HTML Files.w"
char * Formats__HTML__translate_colour_name(char *original) ;
#line 97 "inform7/Chapter 3/Javascript Pastes.w"
void Formats__HTML__Javascript__paste(OUTPUT_STREAM, int from, int to, char *alt_text) ;
#line 124 "inform7/Chapter 3/Javascript Pastes.w"
void Formats__HTML__Javascript__open_file(OUTPUT_STREAM, char *path1, char *path2, char *contents) ;
#line 157 "inform7/Chapter 3/Javascript Pastes.w"
void javascript_string_out(OUTPUT_STREAM, int from, int to, char *C_string) ;
#line 262 "inform7/Chapter 3/Javascript Pastes.w"
void javascript_char_out(OUTPUT_STREAM, char c) ;
#line 46 "inform7/Chapter 3/HTML Documentation.w"
void href_of_example(OUTPUT_STREAM, char *base_leafname, int to_example_variant, int to_example_anchor) ;
#line 76 "inform7/Chapter 3/HTML Documentation.w"
int extension_documentation_heading(int w1, int w2, int *level, int *hn1, int *hn2) ;
#line 110 "inform7/Chapter 3/HTML Documentation.w"
int extension_documentation_example(int w1, int w2, int *asterisks, int *egn1, int *egn2, int *egr1, int *egr2) ;
#line 146 "inform7/Chapter 3/HTML Documentation.w"
void Extensions__Documentation__HTML__set_table_of_contents(int w1, int w2, OUTPUT_STREAM, char *base_leafname) ;
#line 228 "inform7/Chapter 3/HTML Documentation.w"
int Extensions__Documentation__HTML__set_body_text(int w1, int w2, OUTPUT_STREAM, int example_which_is_open, char *base_leafname) ;
#line 93 "inform7/Chapter 3/Index File Services.w"
void Index__set_thumbnail_image(char *image, char *caption) ;
#line 101 "inform7/Chapter 3/Index File Services.w"
void Index__new_page(char *col) ;
#line 129 "inform7/Chapter 3/Index File Services.w"
void Index__new_segment(char *abb, char *title, char *explanation) ;
#line 147 "inform7/Chapter 3/Index File Services.w"
void Index__open_file(char *index_leaf, char *title, int sub, char *explanation) ;
#line 327 "inform7/Chapter 3/Index File Services.w"
void index_banner_line(int N, char *sym, char *name, char *exp, char *link) ;
#line 361 "inform7/Chapter 3/Index File Services.w"
void Index__scripting(void) ;
#line 634 "inform7/Chapter 3/Index File Services.w"
void index_actual_element(char *elt) ;
#line 750 "inform7/Chapter 3/Index File Services.w"
void Index__explain(char *explanation) ;
#line 786 "inform7/Chapter 3/Index File Services.w"
void Index__complete(void) ;
#line 791 "inform7/Chapter 3/Index File Services.w"
void close_index_file(void) ;
#line 812 "inform7/Chapter 3/Index File Services.w"
void Index__link(int wn) ;
#line 816 "inform7/Chapter 3/Index File Services.w"
void Index__link_location(source_location sl) ;
#line 820 "inform7/Chapter 3/Index File Services.w"
void Index__link_to(OUTPUT_STREAM, int wn, int nonbreaking_space) ;
#line 824 "inform7/Chapter 3/Index File Services.w"
void link_to_location(OUTPUT_STREAM, source_location sl, int nonbreaking_space) ;
#line 844 "inform7/Chapter 3/Index File Services.w"
void Index__detail_link(char *stub, int sub, int down) ;
#line 860 "inform7/Chapter 3/Index File Services.w"
void dref_new(parse_node *p) ;
#line 897 "inform7/Chapter 3/Index File Services.w"
char * Index__DocReferences__validate_if_possible(char *temp) ;
#line 909 "inform7/Chapter 3/Index File Services.w"
char * Index__DocReferences__link_if_possible_once(char *temp, char **chap, char **sec) ;
#line 944 "inform7/Chapter 3/Index File Services.w"
int Index__DocReferences__position_of_symbol(int *w1, int *w2) ;
#line 957 "inform7/Chapter 3/Index File Services.w"
void Index__doc_mark_used(char *symb, int at_word) ;
#line 983 "inform7/Chapter 3/Index File Services.w"
void Index__log_statistics(void) ;
#line 1001 "inform7/Chapter 3/Index File Services.w"
void Index__doc_link(char *fn) ;
#line 1005 "inform7/Chapter 3/Index File Services.w"
void Index__doc_fully_link(char *fn) ;
#line 1009 "inform7/Chapter 3/Index File Services.w"
void Index__doc_link_to(OUTPUT_STREAM, char *fn, int full) ;
#line 1028 "inform7/Chapter 3/Index File Services.w"
void Index__doc_fragment(char *fn) ;
#line 1033 "inform7/Chapter 3/Index File Services.w"
void doc_fragment_to(OUTPUT_STREAM, char *fn) ;
#line 1106 "inform7/Chapter 3/Index File Services.w"
documentation_ref * name_to_dr(char *fn) ;
#line 1133 "inform7/Chapter 3/Index File Services.w"
void Index__below_link(char *p) ;
#line 1138 "inform7/Chapter 3/Index File Services.w"
void Index__anchor(char *p) ;
#line 1142 "inform7/Chapter 3/Index File Services.w"
void Index__below_link_numbered(int n) ;
#line 1147 "inform7/Chapter 3/Index File Services.w"
void Index__anchor_numbered(int n) ;
#line 1154 "inform7/Chapter 3/Index File Services.w"
void Index__extra_link(int id) ;
#line 1160 "inform7/Chapter 3/Index File Services.w"
void Index__extra_link_with(int id, char *icon) ;
#line 1172 "inform7/Chapter 3/Index File Services.w"
void Index__noextra_link(void) ;
#line 1179 "inform7/Chapter 3/Index File Services.w"
void Index__extra_div_open(int id, int indent, char *colour) ;
#line 1185 "inform7/Chapter 3/Index File Services.w"
void Index__extra_div_close(char *colour) ;
#line 1190 "inform7/Chapter 3/Index File Services.w"
void Index__extra_div_open_nested(int id, int indent) ;
#line 1195 "inform7/Chapter 3/Index File Services.w"
void Index__extra_div_close_nested(void) ;
#line 1202 "inform7/Chapter 3/Index File Services.w"
void Index__deprecation_icon(int id) ;
#line 1213 "inform7/Chapter 3/Index File Services.w"
void Index__dequote(char *p) ;
#line 56 "inform7/Chapter 3/Lexicon Index.w"
lexicon_entry * lexicon_new_entry(int w1, int w2) ;
#line 71 "inform7/Chapter 3/Lexicon Index.w"
lexicon_entry * Index__Lexicon__new_entry_with_details(int w1, int w2, int pos, word_assemblage wa, char *category, char *gloss) ;
#line 80 "inform7/Chapter 3/Lexicon Index.w"
lexicon_entry * Index__Lexicon__new_main_verb(word_assemblage infinitive, int part) ;
#line 97 "inform7/Chapter 3/Lexicon Index.w"
void lexicon_copy_to_string(lexicon_entry *lex, char *str) ;
#line 108 "inform7/Chapter 3/Lexicon Index.w"
void Index__Lexicon__index(void) ;
#line 128 "inform7/Chapter 3/Lexicon Index.w"
void Index__Lexicon__index_common_nouns(void) ;
#line 439 "inform7/Chapter 3/Lexicon Index.w"
void Index__Lexicon__index_verbs(void) ;
#line 468 "inform7/Chapter 3/Lexicon Index.w"
void Index__Lexicon__list_verbs_in_file(OUTPUT_STREAM, source_file *sf, extension_file *ef) ;
#line 40 "inform7/Chapter 4/Progress Percentages.w"
void Problems__Progress__update_progress_bar(int stage, float proportion) ;
#line 50 "inform7/Chapter 4/Progress Percentages.w"
void Problems__Progress__final_state_of_progress_bar(void) ;
#line 61 "inform7/Chapter 4/Progress Percentages.w"
STREAM * Problems__Progress__begin_outcome(void) ;
#line 67 "inform7/Chapter 4/Progress Percentages.w"
void Problems__Progress__end_outcome(void) ;
#line 11 "inform7/Chapter 4/Problems, Level 0.w"
void Problems__Fatal__issue(char *message) ;
#line 18 "inform7/Chapter 4/Problems, Level 0.w"
void Problems__Fatal__issue2(char *message, char *fn) ;
#line 36 "inform7/Chapter 4/Problems, Level 0.w"
void Problems__Fatal__force_crash(void) ;
#line 33 "inform7/Chapter 4/Problems, Level 1.w"
void Problems__copy_text_into_problem_buffer(int w1, int w2) ;
#line 43 "inform7/Chapter 4/Problems, Level 1.w"
void Problems__redirect_problem_sentence(parse_node *from, parse_node *A, parse_node *B) ;
#line 53 "inform7/Chapter 4/Problems, Level 1.w"
void Problems__copy_source_reference_into_problem_buffer(int w1, int w2) ;
#line 99 "inform7/Chapter 4/Problems, Level 1.w"
int is_problem_buffer_whitespace(char c) ;
#line 115 "inform7/Chapter 4/Problems, Level 1.w"
void output_problem_buffer_to(OUTPUT_STREAM, int indentation) ;
#line 267 "inform7/Chapter 4/Problems, Level 1.w"
void Problems__output_problem_buffer(int indentation) ;
#line 27 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__empty_all_headings(void) ;
#line 30 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__empty_headings(int from_level) ;
#line 48 "inform7/Chapter 4/Problems, Level 2.w"
void find_headings_at(parse_node *sentence) ;
#line 88 "inform7/Chapter 4/Problems, Level 2.w"
void show_problem_location(void) ;
#line 173 "inform7/Chapter 4/Problems, Level 2.w"
void problem_quote(int t, char type, void *v) ;
#line 181 "inform7/Chapter 4/Problems, Level 2.w"
void problem_quote_textual(int t, char type, int w1, int w2) ;
#line 193 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_source(int t, parse_node *p) ;
#line 197 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_source_eliding_begin(int t, parse_node *p) ;
#line 205 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_words(int t, int w1, int w2) ;
#line 206 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_words_as_source(int t, int w1, int w2) ;
#line 211 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_relation(int t, binary_predicate *bp) ;
#line 212 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_extension(int t, extension_file *ef) ;
#line 213 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_phrase(int t, phrase *p) ;
#line 214 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_invocation(int t, invocation *inv) ;
#line 215 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_number(int t, int *num) ;
#line 216 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_object(int t, instance *I) ;
#line 217 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_subject(int t, inference_subject *infs) ;
#line 226 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_table(int t, table *tab) ;
#line 229 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_property(int t, property *p) ;
#line 230 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_text(int t, char *message) ;
#line 231 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_wa(int t, word_assemblage *wa) ;
#line 232 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_spec(int t, specification *spec) ;
#line 233 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_extension_id(int t, extension_identifier *eid) ;
#line 240 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_kind_of(int t, specification *spec) ;
#line 267 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_kind(int t, kind *K) ;
#line 295 "inform7/Chapter 4/Problems, Level 2.w"
int explained_before(char *explanation) ;
#line 316 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__issue_problem_begin(char *message) ;
#line 336 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__issue_problem_end(void) ;
#line 361 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__issue_problem_segment(char *message) ;
#line 557 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__write_reports(int disaster_struck) ;
#line 31 "inform7/Chapter 4/Problems, Level 3.w"
void internal_error_end(void) ;
#line 47 "inform7/Chapter 4/Problems, Level 3.w"
void internal_error_fn(char *p, char *filename, int linenum) ;
#line 65 "inform7/Chapter 4/Problems, Level 3.w"
void internal_error_tu_fn(char *p, char *filename, int linenum) ;
#line 86 "inform7/Chapter 4/Problems, Level 3.w"
void nodal_error_fn(parse_node *pn, char *p, char *filename, int linenum) ;
#line 95 "inform7/Chapter 4/Problems, Level 3.w"
void nodal_check(parse_node *pn, int node_type_required, char *filename, int linenum) ;
#line 119 "inform7/Chapter 4/Problems, Level 3.w"
void internal_error_on_node_type_fn(parse_node *pn, char *filename, int linenum) ;
#line 137 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__s_subtree_error_set_position(meaning_list *ml) ;
#line 140 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__s_subtree_error(char *mess) ;
#line 204 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__problem_documentation_links(OUTPUT_STREAM) ;
#line 236 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__handmade_problem(SIGIL_ARGUMENTS) ;
#line 246 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__limit_problem(SIGIL_ARGUMENTS, char *what_has_run_out, int how_many) ;
#line 261 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__memory_allocation_problem(SIGIL_ARGUMENTS, char *what_has_run_out) ;
#line 281 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__lexical_problem(SIGIL_ARGUMENTS, char *message, char *concerning, char *exp) ;
#line 302 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__unlocated_problem(SIGIL_ARGUMENTS, char *message) ;
#line 318 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__sentence_problem(SIGIL_ARGUMENTS, char *message, char *explanation) ;
#line 331 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__sentence_problem_with_note(SIGIL_ARGUMENTS, char *message, char *explanation, char *note) ;
#line 347 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__sentence_in_detail_problem(SIGIL_ARGUMENTS, int w1, int w2, char *message, char *explanation) ;
#line 364 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__negative_sentence_problem(SIGIL_ARGUMENTS) ;
#line 384 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__assertion_problem(SIGIL_ARGUMENTS, char *message, char *explanation) ;
#line 419 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__diagnose_further(void) ;
#line 449 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__definition_problem(SIGIL_ARGUMENTS, parse_node *q, char *message, char *explanation) ;
#line 460 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__adjective_problem(SIGIL_ARGUMENTS, int ix1, int ix2, int d1, int d2, char *message, char *explanation) ;
#line 478 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__two_sentences_problem(SIGIL_ARGUMENTS, parse_node *other_sentence, char *message, char *explanation) ;
#line 499 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__contradiction_problem(SIGIL_ARGUMENTS, parse_node *A, parse_node *B, instance *I, char *message, char *explanation) ;
#line 515 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__infs_contradiction_problem(SIGIL_ARGUMENTS, parse_node *A, parse_node *B, inference_subject *infs, char *message, char *explanation) ;
#line 537 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__table_problem(SIGIL_ARGUMENTS, table *t, table_column *tc, parse_node *data, char *message) ;
#line 552 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__equation_problem(SIGIL_ARGUMENTS, equation *eqn, char *p, char *text) ;
#line 565 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__equation_symbol_problem(SIGIL_ARGUMENTS, equation *eqn, int w1, int w2, char *text) ;
#line 579 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__inline_problem(SIGIL_ARGUMENTS, phrase *ph, char *definition, char *message) ;
#line 601 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__tcp_problem(SIGIL_ARGUMENTS, tc_problem_kit *tck, char *prototype) ;
#line 623 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__object_problem(SIGIL_ARGUMENTS, instance *I, char *message, char *explanation) ;
#line 634 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__object_problem_at_sentence(SIGIL_ARGUMENTS, instance *I, char *message, char *explanation) ;
#line 646 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__subject_problem_at_sentence(SIGIL_ARGUMENTS, inference_subject *infs, char *message, char *explanation) ;
#line 664 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__subject_creation_problem(SIGIL_ARGUMENTS, inference_subject *subj, char *message, char *explanation) ;
#line 693 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__inference_problem(SIGIL_ARGUMENTS, inference_subject *infs, inference *inf, char *message, char *explanation) ;
#line 712 "inform7/Chapter 4/Problems, Level 3.w"
void property_problem(SIGIL_ARGUMENTS, property *prn, char *message, char *explanation) ;
#line 726 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__extension_problem(SIGIL_ARGUMENTS, extension_file *ef, char *message) ;
#line 742 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__release_problem(SIGIL_ARGUMENTS, char *message, char *filename) ;
#line 752 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__release_problem_at_sentence(SIGIL_ARGUMENTS, char *message, char *filename) ;
#line 768 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__map_problem(SIGIL_ARGUMENTS, parse_node *q, char *message) ;
#line 777 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__map_problem_wanted_but(SIGIL_ARGUMENTS, parse_node *q, char *i_wanted_a, int vw1) ;
#line 794 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__start_problems_report(void) ;
#line 801 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__issue_problems_banner(OUTPUT_STREAM, char *verdict) ;
#line 272 "inform7/Chapter 4/Debugging Log.w"
void Log__open(void) ;
#line 283 "inform7/Chapter 4/Debugging Log.w"
void Log__close(void) ;
#line 300 "inform7/Chapter 4/Debugging Log.w"
void Log__Telemetry__ensure_file(void) ;
#line 316 "inform7/Chapter 4/Debugging Log.w"
void Log__Telemetry__write_note(char *m) ;
#line 326 "inform7/Chapter 4/Debugging Log.w"
void Log__read_further_mandatory_text(void) ;
#line 353 "inform7/Chapter 4/Debugging Log.w"
void Log__new_phase_of_Informs_run(char *p, char *q) ;
#line 362 "inform7/Chapter 4/Debugging Log.w"
void Log__new_stage_of_Informs_run(char *p) ;
#line 377 "inform7/Chapter 4/Debugging Log.w"
int Log__Aspects__on(int aspect) ;
#line 384 "inform7/Chapter 4/Debugging Log.w"
void Log__Aspects__set(int aspect, int state) ;
#line 391 "inform7/Chapter 4/Debugging Log.w"
void set_all_aspects(int new_state) ;
#line 434 "inform7/Chapter 4/Debugging Log.w"
void Log__Aspects__switch_on(int w1, int w2, int new_state) ;
#line 509 "inform7/Chapter 4/Debugging Log.w"
void Log__Aspects__set_from_command_line(char *text) ;
#line 550 "inform7/Chapter 4/Debugging Log.w"
void Log__Tracing__on(int starred, char *heading) ;
#line 571 "inform7/Chapter 4/Debugging Log.w"
void Log__Tracing__phrases(char *text) ;
#line 606 "inform7/Chapter 4/Debugging Log.w"
void show_debugging_settings_with_state(int state) ;
#line 621 "inform7/Chapter 4/Debugging Log.w"
void show_debugging_contents(void) ;
#line 634 "inform7/Chapter 4/Debugging Log.w"
void Log__paste_icons(void) ;
#line 672 "inform7/Chapter 4/Debugging Log.w"
void Log__mlc_backtrace(void) ;
#line 690 "inform7/Chapter 4/Debugging Log.w"
void dlprintf(char *fmt, ...) ;
#line 244 "inform7/Chapter 5/Lexer.w"
void Text__start(void) ;
#line 260 "inform7/Chapter 5/Lexer.w"
void Text__ensure_space_up_to(int n) ;
#line 296 "inform7/Chapter 5/Lexer.w"
void ensure_lexer_hwm_can_be_raised_by(int n, int transfer_partial_word) ;
#line 311 "inform7/Chapter 5/Lexer.w"
void allocate_lexer_workspace_chunk(void) ;
#line 325 "inform7/Chapter 5/Lexer.w"
char * Text__copy_to_memory(char *p) ;
#line 374 "inform7/Chapter 5/Lexer.w"
int Text__is_punctuation(char c) ;
#line 391 "inform7/Chapter 5/Lexer.w"
int Text__indentation_level(int wn) ;
#line 397 "inform7/Chapter 5/Lexer.w"
char break_char_for_indents(int t) ;
#line 406 "inform7/Chapter 5/Lexer.w"
vocabulary_entry * Text__word(int wn) ;
#line 410 "inform7/Chapter 5/Lexer.w"
void Text__set_word(int wn, vocabulary_entry *ve) ;
#line 414 "inform7/Chapter 5/Lexer.w"
int Text__break_before(int wn) ;
#line 418 "inform7/Chapter 5/Lexer.w"
source_file * Text__file_of_origin(int wn) ;
#line 422 "inform7/Chapter 5/Lexer.w"
source_location Text__word_location(int wn) ;
#line 426 "inform7/Chapter 5/Lexer.w"
char * Text__word_raw_text(int wn) ;
#line 430 "inform7/Chapter 5/Lexer.w"
void Text__set_word_raw_text(int wn, char *rt) ;
#line 434 "inform7/Chapter 5/Lexer.w"
char * Text__word_text(int wn) ;
#line 438 "inform7/Chapter 5/Lexer.w"
void Text__set_word_text(int wn, char *rt) ;
#line 442 "inform7/Chapter 5/Lexer.w"
void Text__word_copy(int to, int from) ;
#line 511 "inform7/Chapter 5/Lexer.w"
void reset_lexer(void) ;
#line 552 "inform7/Chapter 5/Lexer.w"
void Text__feed_begins(source_location sl) ;
#line 560 "inform7/Chapter 5/Lexer.w"
void Text__feed_ends(int *range_read_w1, int *range_read_w2, int extra_padding, char *problem_source_description) ;
#line 674 "inform7/Chapter 5/Lexer.w"
void Text__feed_triplet(int last_cr, int cr, int next_cr) ;
#line 731 "inform7/Chapter 5/Lexer.w"
void feed_char_into_lexer(char c) ;
#line 60 "inform7/Chapter 5/Read Source Text.w"
int Text__Reader__read_extension_source_text(extension_file *EF, char *filename, char *synopsis, int documentation_only) ;
#line 67 "inform7/Chapter 5/Read Source Text.w"
void Text__Reader__read_primary_source_text(void) ;
#line 89 "inform7/Chapter 5/Read Source Text.w"
int read_file(char *pathname, char *leafname, char *synopsis, extension_file *EF, int documentation_only) ;
#line 205 "inform7/Chapter 5/Read Source Text.w"
void feed_file_into_lexer(source_file *sf, char *leafname, int documentation_only) ;
#line 258 "inform7/Chapter 5/Read Source Text.w"
int Text__Reader__word_count(int wc) ;
#line 287 "inform7/Chapter 5/Read Source Text.w"
int Text__Reader__sf_total_word_count(source_file *sf) ;
#line 297 "inform7/Chapter 5/Read Source Text.w"
char * Text__Reader__sf_get_filename(source_file *sf) ;
#line 302 "inform7/Chapter 5/Read Source Text.w"
extension_file * Text__Reader__sf_get_extension_corresponding(source_file *sf) ;
#line 307 "inform7/Chapter 5/Read Source Text.w"
source_file * Text__Reader__filename_to_source_file(char *filename) ;
#line 343 "inform7/Chapter 5/Read Source Text.w"
int Text__Reader__utf8_fgetc(FILE *from, char **or_from, int escape_oddities) ;
#line 443 "inform7/Chapter 5/Read Source Text.w"
void Text__feed_into_lexer(char *text, int expand_strings, char *nonstandard) ;
#line 484 "inform7/Chapter 5/Read Source Text.w"
int Text__splice_words(int w1, int w2) ;
#line 499 "inform7/Chapter 5/Read Source Text.w"
int lower_case_splice_words(int w1, int w2) ;
#line 79 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__identify_word(int wn) ;
#line 85 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__identify_word_range(int w1, int w2) ;
#line 94 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__change_text_of_word(int wn, char *new) ;
#line 104 "inform7/Chapter 5/Vocabulary.w"
vocabulary_entry * vocab_entry_new(char *text, int hash_code, unsigned int flags, int val) ;
#line 133 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__log(vocabulary_entry *ve) ;
#line 157 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__set_raw_exemplar_to_text(int wn) ;
#line 165 "inform7/Chapter 5/Vocabulary.w"
char * Text__Vocabulary__get_exemplar(vocabulary_entry *ve, int raw) ;
#line 174 "inform7/Chapter 5/Vocabulary.w"
int Text__Vocabulary__get_literal_number_value(vocabulary_entry *ve) ;
#line 177 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__set_literal_number_value(vocabulary_entry *ve, int val) ;
#line 184 "inform7/Chapter 5/Vocabulary.w"
kind * Text__Vocabulary__get_kind(vocabulary_entry *ve) ;
#line 187 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__set_kind(vocabulary_entry *ve, kind *K) ;
#line 201 "inform7/Chapter 5/Vocabulary.w"
int Text__Vocabulary__used_case_sensitively(vocabulary_entry *ve) ;
#line 205 "inform7/Chapter 5/Vocabulary.w"
vocabulary_entry * Text__Vocabulary__get_lower_case_form(vocabulary_entry *ve) ;
#line 208 "inform7/Chapter 5/Vocabulary.w"
vocabulary_entry * Text__Vocabulary__make_case_sensitive(vocabulary_entry *ve) ;
#line 220 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__set_flags(vocabulary_entry *ve, unsigned int t) ;
#line 223 "inform7/Chapter 5/Vocabulary.w"
unsigned int Text__Vocabulary__test_vflags(vocabulary_entry *ve, unsigned int t) ;
#line 226 "inform7/Chapter 5/Vocabulary.w"
unsigned int Text__Vocabulary__test_flags(int wn, unsigned int t) ;
#line 236 "inform7/Chapter 5/Vocabulary.w"
unsigned int Text__Vocabulary__disjunction_of_flags(int w1, int w2) ;
#line 246 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__set_ntb(vocabulary_entry *ve, int R) ;
#line 249 "inform7/Chapter 5/Vocabulary.w"
int Text__Vocabulary__get_ntb(vocabulary_entry *ve) ;
#line 298 "inform7/Chapter 5/Vocabulary.w"
int hash_code_from_word(char *text) ;
#line 329 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__start_hash_table(void) ;
#line 345 "inform7/Chapter 5/Vocabulary.w"
vocabulary_entry * Text__Vocabulary__entry_for_text(char *text) ;
#line 409 "inform7/Chapter 5/Vocabulary.w"
vocabulary_entry * Text__Vocabulary__entry_for_partial_text(char *str, int from, int to) ;
#line 429 "inform7/Chapter 5/Vocabulary.w"
int an_ordinal_number(char *fw) ;
#line 32 "inform7/Chapter 5/Lexical Services.w"
int Text__compare_word_by_strcmp(int w, char *t) ;
#line 35 "inform7/Chapter 5/Lexical Services.w"
int Text__compare_raw_word_by_strcmp(int w, char *t) ;
#line 47 "inform7/Chapter 5/Lexical Services.w"
int Text__unexpectedly_upper_case(int wn) ;
#line 62 "inform7/Chapter 5/Lexical Services.w"
int Text__singly_quoted(int wn) ;
#line 75 "inform7/Chapter 5/Lexical Services.w"
int Text__text_ending_sentence(int wn) ;
#line 130 "inform7/Chapter 5/Lexical Services.w"
void Text__dequote_word(int wn) ;
#line 160 "inform7/Chapter 5/Lexical Services.w"
int Text__well_formed_text_routine(char *fw) ;
#line 177 "inform7/Chapter 5/Lexical Services.w"
int Text__perhaps_ill_formed_text_routine(char *fw) ;
#line 192 "inform7/Chapter 5/Lexical Services.w"
int Text__compare_word_range(int w1, int w2, int w3, int w4) ;
#line 204 "inform7/Chapter 5/Lexical Services.w"
int Text__compare_perhaps_quoted_word_range(int w1, int w2, int w3, int w4) ;
#line 224 "inform7/Chapter 5/Lexical Services.w"
int Text__rangecmp(int x1, int x2, int y1, int y2) ;
#line 241 "inform7/Chapter 5/Lexical Services.w"
int Text__paired_brackets(int w1, int w2) ;
#line 252 "inform7/Chapter 5/Lexical Services.w"
int Text__mismatched_brackets(int w1, int w2) ;
#line 281 "inform7/Chapter 5/Lexical Services.w"
int Text__last_word_of_formatted_text(int w1, int w2, int tab_flag) ;
#line 309 "inform7/Chapter 5/Lexical Services.w"
void Text__print_literal_string_to_file(OUTPUT_STREAM, char *p) ;
#line 319 "inform7/Chapter 5/Lexical Services.w"
void Text__transcode_ISO_string_to_UTF8(char *p, char *dest) ;
#line 341 "inform7/Chapter 5/Lexical Services.w"
void Text__print_text_to_stream(int w1, int w2, OUTPUT_STREAM) ;
#line 350 "inform7/Chapter 5/Lexical Services.w"
void Text__print_text_to_string(int w1, int w2, char *str) ;
#line 360 "inform7/Chapter 5/Lexical Services.w"
void Text__print_text_to_string_truncated(int w1, int w2, char *str, int max) ;
#line 387 "inform7/Chapter 5/Lexical Services.w"
void Text__print_modest_sized_text_to_string(int w1, int w2, char *str) ;
#line 442 "inform7/Chapter 5/Lexical Services.w"
void Text__print_raw_text_to_stream(int w1, int w2, OUTPUT_STREAM) ;
#line 459 "inform7/Chapter 5/Lexical Services.w"
void Text__print_raw_text_to_string(int w1, int w2, char *str) ;
#line 476 "inform7/Chapter 5/Lexical Services.w"
void Text__print_raw_text_to_string_truncated(int w1, int w2, char *str, int max) ;
#line 501 "inform7/Chapter 5/Lexical Services.w"
void Text__print_raw_text_within_i6_literal(OUTPUT_STREAM, int w1, int w2) ;
#line 522 "inform7/Chapter 5/Lexical Services.w"
void Text__log(int w1, int w2) ;
#line 527 "inform7/Chapter 5/Lexical Services.w"
void Text__log_raw(int w1, int w2) ;
#line 536 "inform7/Chapter 5/Lexical Services.w"
void Text__log_with_whitespace(int w1, int w2) ;
#line 555 "inform7/Chapter 5/Lexical Services.w"
void Text__log_spaceless(int w1, int w2) ;
#line 572 "inform7/Chapter 5/Lexical Services.w"
void Text__log_lexer_output(void) ;
#line 69 "inform7/Chapter 5/Tries and Inflections.w"
match_trie * new_trie_node(int mc) ;
#line 84 "inform7/Chapter 5/Tries and Inflections.w"
match_avinue * Text__Inflections__new_avinue(int from_start) ;
#line 91 "inform7/Chapter 5/Tries and Inflections.w"
match_avinue * Text__Inflections__fresh_avinue(match_avinue *A) ;
#line 132 "inform7/Chapter 5/Tries and Inflections.w"
char * search_trie(match_trie *T, char *p, char *add_outcome) ;
#line 300 "inform7/Chapter 5/Tries and Inflections.w"
int trie_node_matches(match_trie *pos, int c) ;
#line 320 "inform7/Chapter 5/Tries and Inflections.w"
int trie_node_ambiguous(match_trie *pos) ;
#line 330 "inform7/Chapter 5/Tries and Inflections.w"
char * search_avinue(match_avinue *T, char *p) ;
#line 343 "inform7/Chapter 5/Tries and Inflections.w"
void Text__Inflections__log_avinue(match_avinue *A) ;
#line 355 "inform7/Chapter 5/Tries and Inflections.w"
void log_trie_recursively(match_trie *T) ;
#line 383 "inform7/Chapter 5/Tries and Inflections.w"
int suffix_inflection(match_avinue *T, char *to, char *from, int max_length) ;
#line 413 "inform7/Chapter 5/Tries and Inflections.w"
word_assemblage Text__Inflections__apply_trie_to_wa(word_assemblage wa, match_avinue *mt) ;
#line 436 "inform7/Chapter 5/Tries and Inflections.w"
void Text__Inflections__preface_by_article(OUTPUT_STREAM, STREAM *TEMP) ;
#line 452 "inform7/Chapter 5/Tries and Inflections.w"
int Text__Inflections__pluralize(char *to, char *from, int max_length, natural_language *nl) ;
#line 466 "inform7/Chapter 5/Tries and Inflections.w"
int pasturise_participle(char *to, char *from, int max_length) ;
#line 476 "inform7/Chapter 5/Tries and Inflections.w"
void Text__Inflections__test_tries(OUTPUT_STREAM, char *p) ;
#line 492 "inform7/Chapter 5/Tries and Inflections.w"
void Text__Inflections__add_to_avinue(match_avinue *mt, char *from, char *to) ;
#line 503 "inform7/Chapter 5/Tries and Inflections.w"
void Text__make_past_of_participle(int w1, int w2, int *plw1, int *plw2) ;
#line 527 "inform7/Chapter 5/Tries and Inflections.w"
void Text__set_past_participle(int *past_w1, int *past_w2, int irregular_pp) ;
#line 540 "inform7/Chapter 5/Tries and Inflections.w"
int Text__make_comparative(int w1) ;
#line 558 "inform7/Chapter 5/Tries and Inflections.w"
int Text__make_superlative(int w1) ;
#line 578 "inform7/Chapter 5/Tries and Inflections.w"
int Text__make_quiddity(int w1) ;
#line 593 "inform7/Chapter 5/Tries and Inflections.w"
void test_trie_cases(OUTPUT_STREAM) ;
#line 608 "inform7/Chapter 5/Tries and Inflections.w"
void test_trie_case(char *t) ;
#line 32 "inform7/Chapter 5/Word Assemblages.w"
word_assemblage wa_new(void) ;
#line 43 "inform7/Chapter 5/Word Assemblages.w"
word_assemblage Text__Words__from_range(int w1, int w2) ;
#line 55 "inform7/Chapter 5/Word Assemblages.w"
word_assemblage Text__Words__lit_0(void) ;
#line 59 "inform7/Chapter 5/Word Assemblages.w"
word_assemblage Text__Words__lit_1(vocabulary_entry *ve1) ;
#line 68 "inform7/Chapter 5/Word Assemblages.w"
word_assemblage Text__Words__join(word_assemblage wa1, word_assemblage wa2) ;
#line 84 "inform7/Chapter 5/Word Assemblages.w"
void Text__Words__to_range(word_assemblage *wa, int *w1, int *w2) ;
#line 103 "inform7/Chapter 5/Word Assemblages.w"
void Text__Words__truncate(word_assemblage *wa, int n) ;
#line 112 "inform7/Chapter 5/Word Assemblages.w"
void Text__Words__truncate_to(word_assemblage *wa, int n) ;
#line 121 "inform7/Chapter 5/Word Assemblages.w"
int Text__Words__nonempty(word_assemblage wa1) ;
#line 126 "inform7/Chapter 5/Word Assemblages.w"
void Text__Words__copy_to_stream(OUTPUT_STREAM, word_assemblage *wa) ;
#line 134 "inform7/Chapter 5/Word Assemblages.w"
void Text__Words__copy_to_string(word_assemblage *wa, char *str) ;
#line 143 "inform7/Chapter 5/Word Assemblages.w"
vocabulary_entry * Text__Words__hyphenated(word_assemblage *wa) ;
#line 158 "inform7/Chapter 5/Word Assemblages.w"
void Text__Words__as_array(word_assemblage *wa, vocabulary_entry ***array, int *len) ;
#line 166 "inform7/Chapter 5/Word Assemblages.w"
int Text__Words__compare(word_assemblage *wa1, word_assemblage *wa2) ;
#line 177 "inform7/Chapter 5/Word Assemblages.w"
int Text__Words__compare_with_range(word_assemblage *wa, int w1, int w2) ;
#line 191 "inform7/Chapter 5/Word Assemblages.w"
int Text__Words__parse_as_strictly_initial_text(int w1, int w2, word_assemblage *wa) ;
#line 195 "inform7/Chapter 5/Word Assemblages.w"
int Text__Words__parse_as_weakly_initial_text(int w1, int w2, word_assemblage *wa, int str1, int str2, int allow_uuc, int allow_to_fill) ;
#line 215 "inform7/Chapter 5/Word Assemblages.w"
vocabulary_entry * Text__Words__last_word(word_assemblage *wa) ;
#line 220 "inform7/Chapter 5/Word Assemblages.w"
vocabulary_entry * Text__Words__first_word(word_assemblage *wa) ;
#line 228 "inform7/Chapter 5/Word Assemblages.w"
void Text__Words__log(word_assemblage *wa) ;
#line 238 "inform7/Chapter 5/Word Assemblages.w"
void Text__Words__index(word_assemblage *wa) ;
#line 60 "inform7/Chapter 5/Clusters.w"
cluster * Text__Clusters__new(void) ;
#line 69 "inform7/Chapter 5/Clusters.w"
individual_name * Text__Clusters__add(cluster *names, int w1, int w2, natural_language *foreign_language, int gender, int number, int pluralise) ;
#line 120 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__add_with_agreements(cluster *cl, int w1, int w2, natural_language *nl) ;
#line 178 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__set_plural_name(cluster *cl, int pw1, int pw2) ;
#line 196 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__get_name(cluster *cl, int *w1, int *w2, int plural_flag) ;
#line 212 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__get_name_in_play(cluster *cl, int *w1, int *w2, int plural_flag) ;
#line 229 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__get_name_general(cluster *cl, int *w1, int *w2, natural_language *nl, int number_sought, int gender_sought) ;
#line 248 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__set_principal_meaning(individual_name *in, excerpt_meaning *em) ;
#line 253 "inform7/Chapter 5/Clusters.w"
excerpt_meaning * Text__Clusters__get_principal_meaning(cluster *cl) ;
#line 271 "inform7/Chapter 5/Clusters.w"
void handle_plural_definition(parse_node *p) ;
#line 275 "inform7/Chapter 5/Clusters.w"
void Text__traverse_for_plural_definitions(void) ;
#line 294 "inform7/Chapter 5/Clusters.w"
void register_plural_form(int sing_w1, int sing_w2, int pl_w1, int pl_w2) ;
#line 341 "inform7/Chapter 5/Clusters.w"
plural_dictionary_entry * make_plural_of(int w1, int w2, int *plw1, int *plw2, plural_dictionary_entry *search_from, natural_language *nl) ;
#line 98 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__scan(void) ;
#line 131 "inform7/Chapter 5/Natural Languages.w"
void scan_bundles_from(char *pathname, char *origin) ;
#line 250 "inform7/Chapter 5/Natural Languages.w"
natural_language * Text__Languages__get_nl(char *name) ;
#line 267 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__log(natural_language *nl) ;
#line 275 "inform7/Chapter 5/Natural Languages.w"
char * Text__Languages__get_name(natural_language *nl) ;
#line 307 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__stock_nl_kind(kind *K) ;
#line 328 "inform7/Chapter 5/Natural Languages.w"
int Text__Languages__adaptive_person(natural_language *nl) ;
#line 346 "inform7/Chapter 5/Natural Languages.w"
natural_language * Text__Languages__English(void) ;
#line 354 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__set_language_of_play(natural_language *nl) ;
#line 365 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__write_language_code(OUTPUT_STREAM, natural_language *nl) ;
#line 385 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__include_required(void) ;
#line 411 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__load_preform(natural_language *nl) ;
#line 377 "inform7/Chapter 5/Preform.w"
void Text__Languages__log_language(void) ;
#line 416 "inform7/Chapter 5/Preform.w"
void Text__Languages__log_production(production *pr, int detailed) ;
#line 428 "inform7/Chapter 5/Preform.w"
void log_ptoken(ptoken *pt, int detailed) ;
#line 450 "inform7/Chapter 5/Preform.w"
void Text__Languages__write_ptoken(OUTPUT_STREAM, ptoken *pt) ;
#line 480 "inform7/Chapter 5/Preform.w"
void Text__Languages__watch(nonterminal *nt, int state) ;
#line 505 "inform7/Chapter 5/Preform.w"
void Text__Languages__read_definition(void) ;
#line 599 "inform7/Chapter 5/Preform.w"
int Text__Languages__parse_preform(int w1, int w2, int break_first) ;
#line 705 "inform7/Chapter 5/Preform.w"
nonterminal * find_nonterminal(vocabulary_entry *ve) ;
#line 741 "inform7/Chapter 5/Preform.w"
production * new_production(int w1, int w2, nonterminal *nt, int pc) ;
#line 864 "inform7/Chapter 5/Preform.w"
ptoken * parse_slashed_chain(nonterminal *nt, production *pr, int wn, int unescaped) ;
#line 918 "inform7/Chapter 5/Preform.w"
ptoken * new_ptoken(vocabulary_entry *ve, int unescaped, nonterminal *nt, int pc) ;
#line 971 "inform7/Chapter 5/Preform.w"
void optimise_counts(void) ;
#line 1015 "inform7/Chapter 5/Preform.w"
void optimise_nt(nonterminal *nt) ;
#line 1225 "inform7/Chapter 5/Preform.w"
void optimise_nt_reqs(nonterminal *nt) ;
#line 1238 "inform7/Chapter 5/Preform.w"
void optimise_req(range_requirement *req, range_requirement *prev) ;
#line 1266 "inform7/Chapter 5/Preform.w"
void Text__Languages__mark_as_preposition(vocabulary_entry *ve) ;
#line 1272 "inform7/Chapter 5/Preform.w"
void Text__Languages__mark_as_verb(vocabulary_entry *ve) ;
#line 1285 "inform7/Chapter 5/Preform.w"
void Text__Languages__mark_as_cardinal(vocabulary_entry *ve) ;
#line 1289 "inform7/Chapter 5/Preform.w"
void Text__Languages__mark_as_ordinal(vocabulary_entry *ve) ;
#line 1293 "inform7/Chapter 5/Preform.w"
void mark_nt_as_requiring_itself(nonterminal *nt) ;
#line 1298 "inform7/Chapter 5/Preform.w"
void mark_nt_as_requiring_itself_first(nonterminal *nt) ;
#line 1305 "inform7/Chapter 5/Preform.w"
void mark_nt_as_requiring_itself_conj(nonterminal *nt) ;
#line 1314 "inform7/Chapter 5/Preform.w"
void mark_nt_as_requiring_itself_articled(nonterminal *nt) ;
#line 1321 "inform7/Chapter 5/Preform.w"
void set_nt_incidence(vocabulary_entry *ve, nonterminal *nt) ;
#line 1332 "inform7/Chapter 5/Preform.w"
int nt_bitmap_bit(nonterminal *nt) ;
#line 1361 "inform7/Chapter 5/Preform.w"
int Text__Languages__test_word(int wn, nonterminal *nt) ;
#line 1367 "inform7/Chapter 5/Preform.w"
void Text__Languages__mark_word(int wn, nonterminal *nt) ;
#line 1371 "inform7/Chapter 5/Preform.w"
void Text__Languages__mark_vocabulary(vocabulary_entry *ve, nonterminal *nt) ;
#line 1375 "inform7/Chapter 5/Preform.w"
int Text__Languages__test_vocabulary(vocabulary_entry *ve, nonterminal *nt) ;
#line 1381 "inform7/Chapter 5/Preform.w"
int get_range_disjunction(int w1, int w2) ;
#line 1388 "inform7/Chapter 5/Preform.w"
int get_range_conjunction(int w1, int w2) ;
#line 1400 "inform7/Chapter 5/Preform.w"
int nt_bitmap_violates(int w1, int w2, range_requirement *req) ;
#line 1464 "inform7/Chapter 5/Preform.w"
void concatenate_rreq(range_requirement *req, range_requirement *with) ;
#line 1479 "inform7/Chapter 5/Preform.w"
int concatenate_ds(int m1, int m2) ;
#line 1488 "inform7/Chapter 5/Preform.w"
int concatenate_cs(int m1, int m2) ;
#line 1499 "inform7/Chapter 5/Preform.w"
int concatenate_dw(int m1, int m2) ;
#line 1510 "inform7/Chapter 5/Preform.w"
int concatenate_cw(int m1, int m2) ;
#line 1519 "inform7/Chapter 5/Preform.w"
int concatenate_fs(int m1, int m2) ;
#line 1523 "inform7/Chapter 5/Preform.w"
int concatenate_fw(int m1, int m2) ;
#line 1532 "inform7/Chapter 5/Preform.w"
void disjoin_rreq(range_requirement *req, range_requirement *with) ;
#line 1547 "inform7/Chapter 5/Preform.w"
int disjoin_ds(int m1, int m2) ;
#line 1556 "inform7/Chapter 5/Preform.w"
int disjoin_cs(int m1, int m2) ;
#line 1565 "inform7/Chapter 5/Preform.w"
int disjoin_dw(int m1, int m2) ;
#line 1574 "inform7/Chapter 5/Preform.w"
int disjoin_cw(int m1, int m2) ;
#line 1580 "inform7/Chapter 5/Preform.w"
int disjoin_fw(int m1, int m2) ;
#line 1584 "inform7/Chapter 5/Preform.w"
int disjoin_fs(int m1, int m2) ;
#line 1588 "inform7/Chapter 5/Preform.w"
void clear_rreq(range_requirement *req) ;
#line 1594 "inform7/Chapter 5/Preform.w"
void atomic_rreq(range_requirement *req, nonterminal *nt) ;
#line 1601 "inform7/Chapter 5/Preform.w"
void log_range_requirement(range_requirement *req) ;
#line 1615 "inform7/Chapter 5/Preform.w"
int ptoken_width(ptoken *pt) ;
#line 1629 "inform7/Chapter 5/Preform.w"
void ptoken_extrema(ptoken *pt, int *min_t, int *max_t) ;
#line 1691 "inform7/Chapter 5/Preform.w"
int parse_nt_against_word_range(nonterminal *nt, int w1, int w2, int *result, void **result_p) ;
#line 2181 "inform7/Chapter 5/Preform.w"
int next_strut_posn_after(int w1, int w2, ptoken *start, int len, int from) ;
#line 2207 "inform7/Chapter 5/Preform.w"
int parse_fixed_word_ptoken(int wn, ptoken *pt) ;
#line 84 "inform7/Chapter 5/Non-Parsing Preform.w"
word_assemblage Text__Languages__merge(nonterminal *nt, int pnum, word_assemblage ingredient) ;
#line 112 "inform7/Chapter 5/Non-Parsing Preform.w"
word_assemblage Text__Languages__wording(nonterminal *nt, int pnum) ;
#line 119 "inform7/Chapter 5/Non-Parsing Preform.w"
vocabulary_entry * Text__Languages__word(nonterminal *nt, int pnum) ;
#line 133 "inform7/Chapter 5/Non-Parsing Preform.w"
vocabulary_entry * Text__Languages__replace_word(vocabulary_entry *ve, nonterminal *nt_from, nonterminal *nt_to) ;
#line 167 "inform7/Chapter 5/Non-Parsing Preform.w"
void Text__Languages__enter_lexicon(nonterminal *nt_from, int pos, char *category, char *gloss) ;
#line 195 "inform7/Chapter 5/Non-Parsing Preform.w"
match_avinue * Text__Languages__define_trie(nonterminal *nt, int end, natural_language *nl) ;
#line 299 "inform7/Chapter 5/Non-Parsing Preform.w"
void log_avinues(void) ;
#line 328 "inform7/Chapter 5/Non-Parsing Preform.w"
verb_conjugation * Text__Languages__conjugate_verb(word_assemblage base_text, word_assemblage *overrides, int no_overrides, natural_language *nl) ;
#line 494 "inform7/Chapter 5/Non-Parsing Preform.w"
nonterminal * 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 5/Non-Parsing Preform.w"
word_assemblage 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 5/Non-Parsing Preform.w"
word_assemblage expand_wa_with_endings(vocabulary_entry *ve, word_assemblage *verb_forms) ;
#line 856 "inform7/Chapter 5/Non-Parsing Preform.w"
word_assemblage shorten_wa_with_contractions(word_assemblage wa) ;
#line 908 "inform7/Chapter 5/Non-Parsing Preform.w"
int ptoken_to_verb_form_number(ptoken *pt) ;
#line 914 "inform7/Chapter 5/Non-Parsing Preform.w"
int ve_to_verb_form_number(vocabulary_entry *ve) ;
#line 926 "inform7/Chapter 5/Non-Parsing Preform.w"
int ptoken_to_tense_indicator(ptoken *pt, int *set_sense) ;
#line 953 "inform7/Chapter 5/Non-Parsing Preform.w"
int ptoken_as_bracket(ptoken *pt) ;
#line 966 "inform7/Chapter 5/Non-Parsing Preform.w"
int compare_ve_with_tails(vocabulary_entry *ve, vocabulary_entry *pattern) ;
#line 987 "inform7/Chapter 5/Non-Parsing Preform.w"
void trie_definition_error(nonterminal *nt, production *pr, char *message) ;
#line 994 "inform7/Chapter 5/Non-Parsing Preform.w"
void conjugation_error(word_assemblage base_text, nonterminal *nt, production *pr, char *message) ;
#line 1003 "inform7/Chapter 5/Non-Parsing Preform.w"
void general_npp_error(word_assemblage base_text, nonterminal *nt, production *pr, char *message) ;
#line 1051 "inform7/Chapter 5/Non-Parsing Preform.w"
void Semantics__test_conjugation(OUTPUT_STREAM, int w1, int w2) ;
#line 1059 "inform7/Chapter 5/Non-Parsing Preform.w"
void write_conjugation(OUTPUT_STREAM, verb_conjugation *vc) ;
#line 1102 "inform7/Chapter 5/Non-Parsing Preform.w"
void Semantics__test_participle(OUTPUT_STREAM, int w1, int w2) ;
#line 1110 "inform7/Chapter 5/Non-Parsing Preform.w"
void write_participle(OUTPUT_STREAM, verb_conjugation *vc) ;
#line 221 "inform7/Chapter 6/Parse Tree.w"
parse_node * Parser__Nodes__new(int type) ;
#line 234 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__type(parse_node *pn) ;
#line 235 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__set_node_type(parse_node *pn, int nt) ;
#line 242 "inform7/Chapter 6/Parse Tree.w"
parse_node_annotation * pna_new(int koa) ;
#line 258 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__has_annotation(parse_node *PN, int koa) ;
#line 272 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__int_annotation(parse_node *PN, int koa) ;
#line 281 "inform7/Chapter 6/Parse Tree.w"
general_pointer pn_pointer_annotation(parse_node *PN, int koa) ;
#line 295 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__annotate_int(parse_node *PN, int koa, int v) ;
#line 314 "inform7/Chapter 6/Parse Tree.w"
void pn_annotate_pointer(parse_node *PN, int koa, general_pointer data) ;
#line 377 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__copy(parse_node *to, parse_node *from) ;
#line 393 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__deep_copy_tree(parse_node *from, parse_node *to, int level) ;
#line 415 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__contains(parse_node *PN, parse_node *to_find) ;
#line 436 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__left_edge_of(parse_node *PN) ;
#line 450 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__right_edge_of(parse_node *PN) ;
#line 466 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__plant_parse_tree(void) ;
#line 486 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__enable_last_sentence_cacheing(void) ;
#line 491 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__disable_last_sentence_cacheing(void) ;
#line 509 "inform7/Chapter 6/Parse Tree.w"
parse_node * Parser__Nodes__graft(parse_node *newborn, parse_node *parent) ;
#line 535 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__is_adjlist(parse_node *p) ;
#line 551 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__log(parse_node *p) ;
#line 554 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__log_subtree_at_current_margin(parse_node *p) ;
#line 564 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__log_subtree(parse_node *p, int indentation) ;
#line 570 "inform7/Chapter 6/Parse Tree.w"
void log_subtree_recursively(parse_node *p, int indentation) ;
#line 582 "inform7/Chapter 6/Parse Tree.w"
void log_single_node(parse_node *p, int indentation) ;
#line 33 "inform7/Chapter 6/Sentences.w"
void Parser__Sentences__declare_source_loaded(void) ;
#line 45 "inform7/Chapter 6/Sentences.w"
void Parser__Sentences__break_source(void) ;
#line 85 "inform7/Chapter 6/Sentences.w"
void Parser__Sentences__break(int w1, int w2, extension_file *from_extension, parse_node *insertion_point) ;
#line 278 "inform7/Chapter 6/Sentences.w"
void Parser__Sentences__make_node(int w1, int w2, char stop_character, parse_node *insertion_point) ;
#line 771 "inform7/Chapter 6/Sentences.w"
void insert_sentence_in_parse_tree(parse_node *new, parse_node *insertion_point) ;
#line 106 "inform7/Chapter 6/Virtual Machines.w"
void Code__VirtualMachines__set_identifier(char *file_extension) ;
#line 123 "inform7/Chapter 6/Virtual Machines.w"
int Code__VirtualMachines__is_16_bit(void) ;
#line 133 "inform7/Chapter 6/Virtual Machines.w"
int Code__VirtualMachines__allow_this_many_locals(int N) ;
#line 139 "inform7/Chapter 6/Virtual Machines.w"
int Code__VirtualMachines__allow_MAX_LOCAL_VARIABLES(void) ;
#line 148 "inform7/Chapter 6/Virtual Machines.w"
int Code__VirtualMachines__supports(kind *K) ;
#line 161 "inform7/Chapter 6/Virtual Machines.w"
char * Code__VirtualMachines__get_blorbed_extension(void) ;
#line 171 "inform7/Chapter 6/Virtual Machines.w"
char * Code__VirtualMachines__get_default_interpreter(void) ;
#line 197 "inform7/Chapter 6/Virtual Machines.w"
void match_VM_against(int w1, int w2) ;
#line 324 "inform7/Chapter 6/Virtual Machines.w"
void plot_VM_icon(OUTPUT_STREAM, int minor) ;
#line 330 "inform7/Chapter 6/Virtual Machines.w"
void Code__VirtualMachines__write_key(OUTPUT_STREAM) ;
#line 344 "inform7/Chapter 6/Virtual Machines.w"
void Code__VirtualMachines__index_innards(void) ;
#line 357 "inform7/Chapter 6/Virtual Machines.w"
void Code__VirtualMachines__write_current(void) ;
#line 378 "inform7/Chapter 6/Virtual Machines.w"
void Code__VirtualMachines__write_icons(OUTPUT_STREAM, int w1, int w2) ;
#line 435 "inform7/Chapter 6/Virtual Machines.w"
void Code__VirtualMachines__note_usage(char *cat, int w1, int w2, char *name, int words, int bytes, int each) ;
#line 453 "inform7/Chapter 6/Virtual Machines.w"
void index_memory_usage(void) ;
#line 502 "inform7/Chapter 6/Virtual Machines.w"
int compare_VM_usage_notes(const void *ent1, const void *ent2) ;
#line 524 "inform7/Chapter 6/Virtual Machines.w"
int Code__VirtualMachines__get_next_free_blorb_resource_ID(void) ;
#line 210 "inform7/Chapter 6/Headings.w"
heading * Parser__Sentences__Headings__declare(parse_node *PN) ;
#line 364 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__make_tree(void) ;
#line 431 "inform7/Chapter 6/Headings.w"
void make_child_heading(heading *ch, heading *pa) ;
#line 480 "inform7/Chapter 6/Headings.w"
void verify_heading_tree(void) ;
#line 485 "inform7/Chapter 6/Headings.w"
void verify_heading_tree_recursively(heading *h, int depth) ;
#line 503 "inform7/Chapter 6/Headings.w"
int Parser__Sentences__Headings__include_material(heading *h) ;
#line 510 "inform7/Chapter 6/Headings.w"
int Parser__Sentences__Headings__indexed(heading *h) ;
#line 518 "inform7/Chapter 6/Headings.w"
extension_file * Parser__Sentences__Headings__get_extension_containing(heading *h) ;
#line 529 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__get_text(heading *h, int *w1, int *w2) ;
#line 547 "inform7/Chapter 6/Headings.w"
heading * Parser__Sentences__Headings__heading_of(source_location sl) ;
#line 566 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__satisfy_dependencies(void) ;
#line 578 "inform7/Chapter 6/Headings.w"
void satisfy_individual_heading_dependency(heading *h) ;
#line 631 "inform7/Chapter 6/Headings.w"
void excise_material_under(heading *h, parse_node *transfer_to) ;
#line 728 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__attach_nametag(nametag *new_tag) ;
#line 749 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__verify_divisions(void) ;
#line 846 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__disturb(void) ;
#line 855 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__construct_nametag_search_list(void) ;
#line 940 "inform7/Chapter 6/Headings.w"
void build_search_list_from(heading *within, heading *way_we_came, int p) ;
#line 977 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__set_nametag_search_score(nametag *nt, int v) ;
#line 981 "inform7/Chapter 6/Headings.w"
nametag * Parser__Sentences__Headings__highest_scoring_nametag_searched(void) ;
#line 1001 "inform7/Chapter 6/Headings.w"
void handle_heading(parse_node *PN) ;
#line 1010 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__log(heading *h) ;
#line 1024 "inform7/Chapter 6/Headings.w"
void log_all_headings(void) ;
#line 1031 "inform7/Chapter 6/Headings.w"
void log_headings_recursively(heading *h, int depth) ;
#line 1045 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__index(void) ;
#line 1109 "inform7/Chapter 6/Headings.w"
void index_heading_recursively(heading *h) ;
#line 1170 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__write_as_xml(void) ;
#line 1179 "inform7/Chapter 6/Headings.w"
void write_headings_as_xml_inner(OUTPUT_STREAM) ;
#line 150 "inform7/Chapter 6/Verb Phrases.w"
void Parser__Sentences__VPs__traverse(void) ;
#line 197 "inform7/Chapter 6/Verb Phrases.w"
void Parser__Sentences__VPs__seek(parse_node *PN) ;
#line 231 "inform7/Chapter 6/Verb Phrases.w"
void switch_dl_mode(parse_node *PN, int sense) ;
#line 447 "inform7/Chapter 6/Verb Phrases.w"
int nss_tree1(int t, int verb_w1, int verb_w2, parse_node *np1) ;
#line 456 "inform7/Chapter 6/Verb Phrases.w"
int nss_tree2(int t, int verb_w1, int verb_w2, parse_node *np1, parse_node *np2) ;
#line 466 "inform7/Chapter 6/Verb Phrases.w"
int nss_tree3(int t, int verb_w1, int verb_w2, parse_node *np1, parse_node *np2, parse_node *np3) ;
#line 886 "inform7/Chapter 6/Verb Phrases.w"
void Parser__Sentences__VPs__log(int verb_number) ;
#line 41 "inform7/Chapter 6/Noun Phrases.w"
parse_node * Parser__Sentences__NPs__new_raw(int w1, int w2) ;
#line 112 "inform7/Chapter 6/Noun Phrases.w"
parse_node * Parser__Sentences__NPs__annotate_by_articles(parse_node *RAW_NP) ;
#line 467 "inform7/Chapter 6/Noun Phrases.w"
parse_node * PN_void(int t, int w1, int w2) ;
#line 474 "inform7/Chapter 6/Noun Phrases.w"
parse_node * PN_single(int t, int w1, int w2, parse_node *A) ;
#line 482 "inform7/Chapter 6/Noun Phrases.w"
parse_node * PN_pair(int t, int w1, int w2, parse_node *A, parse_node *B) ;
#line 498 "inform7/Chapter 6/Noun Phrases.w"
parse_node * PN_rel(int w1, int w2, binary_predicate *R, int reln_type, parse_node *referent) ;
#line 525 "inform7/Chapter 6/Noun Phrases.w"
int Parser__Sentences__NPs__turn_player_to_yourself(parse_node *pn) ;
#line 62 "inform7/Chapter 6/Of and From.w"
void expunge_X_OF_Y_subtree(parse_node *pn) ;
#line 68 "inform7/Chapter 6/Of and From.w"
void expunge_FROM_subtree(parse_node *pn) ;
#line 85 "inform7/Chapter 6/Of and From.w"
void convert_clause_to_RELATIONSHIP(parse_node *pn) ;
#line 114 "inform7/Chapter 6/Of and From.w"
void Parser__Sentences__tidy_up_ofs_and_froms(void) ;
#line 140 "inform7/Chapter 6/Of and From.w"
void traverse_for_property_names(parse_node *pn) ;
#line 155 "inform7/Chapter 6/Of and From.w"
void Parser__Sentences__check_sentence_for_direction_creation(parse_node *pn) ;
#line 178 "inform7/Chapter 6/Of and From.w"
binary_predicate * Parser__Sentences__relation_noticed(int i) ;
#line 341 "inform7/Chapter 6/Of and From.w"
void traverse_for_nonbreaking_ofs(parse_node *pn) ;
#line 377 "inform7/Chapter 6/Of and From.w"
void traverse_for_FROM_NT_subtrees(parse_node *pn) ;
#line 60 "inform7/Chapter 6/Rule Subtrees.w"
void Parser__Sentences__register_recently_lexed_phrases(void) ;
#line 93 "inform7/Chapter 6/Rule Subtrees.w"
void unify_block_syntaxes(parse_node *rout) ;
#line 548 "inform7/Chapter 6/Rule Subtrees.w"
control_structure_phrase * csp_new(void) ;
#line 559 "inform7/Chapter 6/Rule Subtrees.w"
void Parser__Sentences__create_standard_csps(void) ;
#line 595 "inform7/Chapter 6/Rule Subtrees.w"
int Parser__Sentences__is_otherwise_if(int w1, int w2) ;
#line 600 "inform7/Chapter 6/Rule Subtrees.w"
control_structure_phrase * Parser__Sentences__detect_control_structure(int w1, int w2) ;
#line 152 "inform7/Chapter 6/Verify Parse Tree.w"
void Parser__Nodes__Types__log(int t) ;
#line 157 "inform7/Chapter 6/Verify Parse Tree.w"
char * Parser__Nodes__Types__get_name(int t) ;
#line 175 "inform7/Chapter 6/Verify Parse Tree.w"
void Parser__Nodes__verify_integrity(parse_node *p, int worth_logging) ;
#line 198 "inform7/Chapter 6/Verify Parse Tree.w"
void tidy_tree_after_verification(parse_node *p) ;
#line 212 "inform7/Chapter 6/Verify Parse Tree.w"
void verify_tree_integrity_recursively(parse_node *p, parse_node *from, char *way, int depth) ;
#line 250 "inform7/Chapter 6/Verify Parse Tree.w"
void Parser__Nodes__verify(void) ;
#line 269 "inform7/Chapter 6/Verify Parse Tree.w"
void verify_initial_parse_tree_invariant(parse_node *p, parse_node *parent, int current_weight) ;
#line 355 "inform7/Chapter 6/Verify Parse Tree.w"
int Parser__Nodes__Types__allow_in_assertions(parse_node *subtree) ;
#line 190 "inform7/Chapter 7/Extension Files.w"
extension_file * Extensions__Files__new(int author_w1, int author_w2, int nw1, int nw2, int vm1, int vm2, int version_word) ;
#line 252 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__set_rubric(extension_file *ef, char *text) ;
#line 257 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__set_extra_credit(extension_file *ef, char *text) ;
#line 267 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__set_corresponding_source_file(extension_file *ef, source_file *sf) ;
#line 271 "inform7/Chapter 7/Extension Files.w"
source_file * Extensions__Files__get_corresponding_source_file(extension_file *ef) ;
#line 278 "inform7/Chapter 7/Extension Files.w"
extension_identifier * Extensions__Files__get_eid(extension_file *ef) ;
#line 285 "inform7/Chapter 7/Extension Files.w"
int Extensions__Files__get_version_wn(extension_file *ef) ;
#line 296 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__set_authorial_modesty(extension_file *ef) ;
#line 297 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__set_general_authorial_modesty(void) ;
#line 305 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__write_name_to_file(extension_file *ef, OUTPUT_STREAM) ;
#line 309 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__write_author_to_file(extension_file *ef, OUTPUT_STREAM) ;
#line 316 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__log(extension_file *ef) ;
#line 325 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__write_I6_comment_describing(extension_file *ef, OUTPUT_STREAM) ;
#line 340 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__write_full_title_to_stream(OUTPUT_STREAM, extension_file *ef) ;
#line 357 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__check_versions(void) ;
#line 405 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__ShowExtensionVersions_routine(OUTPUT_STREAM) ;
#line 435 "inform7/Chapter 7/Extension Files.w"
void credit_ef(OUTPUT_STREAM, extension_file *ef, int with_newline) ;
#line 452 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__index(void) ;
#line 463 "inform7/Chapter 7/Extension Files.w"
void index_extensions_from(extension_file *from) ;
#line 527 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__handle_census_mode(void) ;
#line 537 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__update_census(void) ;
#line 553 "inform7/Chapter 7/Extension Files.w"
void write_sketchy_documentation_for_extensions_found(void) ;
#line 589 "inform7/Chapter 7/Extension Files.w"
void write_top_level_of_extensions_documentation(void) ;
#line 597 "inform7/Chapter 7/Extension Files.w"
void write_top_level_extensions_page(char *leafname, int content) ;
#line 31 "inform7/Chapter 7/Including Extensions.w"
void Extensions__Inclusion__traverse(void) ;
#line 111 "inform7/Chapter 7/Including Extensions.w"
void fulfill_request_to_include_extension(parse_node *p, parse_node *auth_p) ;
#line 155 "inform7/Chapter 7/Including Extensions.w"
extension_file * Extensions__Inclusion__load(int author_w1, int author_w2, int name_w1, int name_w2, int version_word, int vm1, int vm2) ;
#line 299 "inform7/Chapter 7/Including Extensions.w"
int Extensions__Inclusion__parse_version(int vwn) ;
#line 387 "inform7/Chapter 7/Including Extensions.w"
void Extensions__Inclusion__check_begins_here(parse_node *PN, extension_file *ef) ;
#line 481 "inform7/Chapter 7/Including Extensions.w"
void Extensions__Inclusion__check_ends_here(parse_node *PN, extension_file *ef) ;
#line 521 "inform7/Chapter 7/Including Extensions.w"
void handle_extension_begins(parse_node *PN) ;
#line 525 "inform7/Chapter 7/Including Extensions.w"
void handle_extension_ends(parse_node *PN) ;
#line 80 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__new(extension_identifier *eid, char *an, char *ti, int context) ;
#line 102 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__set_raw(extension_identifier *eid, char *raw_an, char *raw_ti) ;
#line 107 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__write_to_HTML_file(OUTPUT_STREAM, extension_identifier *eid, int fancy) ;
#line 115 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__write_to_I6_file(OUTPUT_STREAM, extension_identifier *eid) ;
#line 123 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__write_to_C_string(char *p, extension_identifier *eid) ;
#line 127 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__write_link_to_HTML_file(OUTPUT_STREAM, extension_identifier *eid) ;
#line 149 "inform7/Chapter 7/Extension Identifiers.w"
int Extensions__IDs__match(extension_identifier *eid1, extension_identifier *eid2) ;
#line 160 "inform7/Chapter 7/Extension Identifiers.w"
int Extensions__IDs__compare(extension_identifier *eid1, extension_identifier *eid2) ;
#line 168 "inform7/Chapter 7/Extension Identifiers.w"
int Extensions__IDs__compare_by_title(extension_identifier *eid1, extension_identifier *eid2) ;
#line 176 "inform7/Chapter 7/Extension Identifiers.w"
int Extensions__IDs__compare_by_date(extension_identifier *eid1, extension_identifier *eid2) ;
#line 186 "inform7/Chapter 7/Extension Identifiers.w"
int Extensions__IDs__compare_by_length(extension_identifier *eid1, extension_identifier *eid2) ;
#line 203 "inform7/Chapter 7/Extension Identifiers.w"
int Extensions__IDs__is_standard_rules(extension_identifier *eid) ;
#line 230 "inform7/Chapter 7/Extension Identifiers.w"
void add_EID_to_database(extension_identifier *eid, int context) ;
#line 257 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__set_usage_date(extension_identifier *eid, char *date) ;
#line 267 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__set_sort_date(extension_identifier *eid, char *date) ;
#line 277 "inform7/Chapter 7/Extension Identifiers.w"
char * Extensions__IDs__get_usage_date(extension_identifier *eid) ;
#line 291 "inform7/Chapter 7/Extension Identifiers.w"
char * get_sort_date(extension_identifier *eid) ;
#line 305 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__set_word_count(extension_identifier *eid, int wc) ;
#line 315 "inform7/Chapter 7/Extension Identifiers.w"
char * get_sort_word_count(extension_identifier *eid) ;
#line 329 "inform7/Chapter 7/Extension Identifiers.w"
char * Extensions__IDs__get_word_count(extension_identifier *eid) ;
#line 339 "inform7/Chapter 7/Extension Identifiers.w"
int Extensions__IDs__no_times_used_in_context(extension_identifier *eid, int context) ;
#line 349 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__log_EID_hash_table(void) ;
#line 372 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__truncated_strcpy(char *to, char *from, int max) ;
#line 384 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__normalise_casing(char *p) ;
#line 401 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__begin_extension_link(OUTPUT_STREAM, extension_identifier *eid, char *rubric) ;
#line 415 "inform7/Chapter 7/Extension Identifiers.w"
void escape_apostrophes(OUTPUT_STREAM, char *p) ;
#line 425 "inform7/Chapter 7/Extension Identifiers.w"
void Extensions__IDs__end_extension_link(OUTPUT_STREAM, extension_identifier *eid) ;
#line 51 "inform7/Chapter 7/Extension Census.w"
void Extensions__Census__perform(void) ;
#line 86 "inform7/Chapter 7/Extension Census.w"
void take_census_of_domain(char *pathname, int origin) ;
#line 112 "inform7/Chapter 7/Extension Census.w"
void census_from(char *pathname, int top_level, int origin, char *parent) ;
#line 534 "inform7/Chapter 7/Extension Census.w"
void begin_recording_census_errors(void) ;
#line 539 "inform7/Chapter 7/Extension Census.w"
int Extensions__Census__currently_recording_errors(void) ;
#line 544 "inform7/Chapter 7/Extension Census.w"
void end_recording_census_errors(void) ;
#line 554 "inform7/Chapter 7/Extension Census.w"
void census_error(char *message, char *auth, char *title, char *claimed_author, char *claimed_title) ;
#line 580 "inform7/Chapter 7/Extension Census.w"
void warn_about_census_errors(OUTPUT_STREAM) ;
#line 595 "inform7/Chapter 7/Extension Census.w"
void transcribe_census_errors(OUTPUT_STREAM) ;
#line 643 "inform7/Chapter 7/Extension Census.w"
void Extensions__Census__write_results(OUTPUT_STREAM) ;
#line 1026 "inform7/Chapter 7/Extension Census.w"
int installation_region(extension_census_datum *ecd) ;
#line 1033 "inform7/Chapter 7/Extension Census.w"
int ecd_used(extension_census_datum *ecd) ;
#line 1045 "inform7/Chapter 7/Extension Census.w"
int compare_ecd_by_title(const void *ecd1, const void *ecd2) ;
#line 1051 "inform7/Chapter 7/Extension Census.w"
int compare_ecd_by_author(const void *ecd1, const void *ecd2) ;
#line 1057 "inform7/Chapter 7/Extension Census.w"
int compare_ecd_by_installation(const void *ecd1, const void *ecd2) ;
#line 1065 "inform7/Chapter 7/Extension Census.w"
int compare_ecd_by_date(const void *ecd1, const void *ecd2) ;
#line 1071 "inform7/Chapter 7/Extension Census.w"
int compare_ecd_by_length(const void *ecd1, const void *ecd2) ;
#line 109 "inform7/Chapter 7/Extension Dictionary.w"
void Extensions__Dictionary__Entries__log(extension_dictionary_entry *ede) ;
#line 115 "inform7/Chapter 7/Extension Dictionary.w"
void log_extension_dictionary(void) ;
#line 137 "inform7/Chapter 7/Extension Dictionary.w"
void erase_entries_of_uninstalled_extensions(void) ;
#line 156 "inform7/Chapter 7/Extension Dictionary.w"
void Extensions__Dictionary__erase_entries(extension_file *ef) ;
#line 171 "inform7/Chapter 7/Extension Dictionary.w"
void Extensions__Dictionary__Entries__new(char *category, extension_file *ef, int w1, int w2) ;
#line 178 "inform7/Chapter 7/Extension Dictionary.w"
void Extensions__Dictionary__Entries__new_str(char *category, extension_file *ef, char *headword) ;
#line 182 "inform7/Chapter 7/Extension Dictionary.w"
void new_dictionary_entry_raw(char *category, char *author, char *title, char *headword) ;
#line 221 "inform7/Chapter 7/Extension Dictionary.w"
void Extensions__Dictionary__load(void) ;
#line 292 "inform7/Chapter 7/Extension Dictionary.w"
void Extensions__Dictionary__time_stamp(extension_file *ef) ;
#line 312 "inform7/Chapter 7/Extension Dictionary.w"
void Extensions__Dictionary__write_back(void) ;
#line 365 "inform7/Chapter 7/Extension Dictionary.w"
int sort_extension_dictionary(void) ;
#line 460 "inform7/Chapter 7/Extension Dictionary.w"
int compare_ed_entries(const void *elem1, const void *elem2) ;
#line 476 "inform7/Chapter 7/Extension Dictionary.w"
known_extension_clash * kec_new(extension_dictionary_entry *L, extension_dictionary_entry *R, int first_known_flag) ;
#line 540 "inform7/Chapter 7/Extension Dictionary.w"
void extension_clash(extension_dictionary_entry *ede1, extension_dictionary_entry *ede2) ;
#line 597 "inform7/Chapter 7/Extension Dictionary.w"
void list_known_extension_clashes(OUTPUT_STREAM) ;
#line 645 "inform7/Chapter 7/Extension Dictionary.w"
void Extensions__Dictionary__write_to_HTML(OUTPUT_STREAM) ;
#line 14 "inform7/Chapter 7/Extension Documentation.w"
void Extensions__Documentation__write_detailed(extension_file *ef) ;
#line 17 "inform7/Chapter 7/Extension Documentation.w"
void Extensions__Documentation__write_sketchy(extension_census_datum *ecd) ;
#line 40 "inform7/Chapter 7/Extension Documentation.w"
void write_extension_documentation(extension_census_datum *ecd, extension_file *ef) ;
#line 61 "inform7/Chapter 7/Extension Documentation.w"
int write_extension_documentation_page(extension_census_datum *ecd, extension_file *ef, int eg_number) ;
#line 419 "inform7/Chapter 7/Extension Documentation.w"
int document_headword(OUTPUT_STREAM, int kc, extension_file *ef, char *par_heading, char *category, int w1, int w2) ;
#line 96 "inform7/Chapter 8/Traverse for Assertions.w"
void Parser__Assertions__traverse(int pass) ;
#line 227 "inform7/Chapter 8/Traverse for Assertions.w"
void switch_sentence_trace(parse_node *PN) ;
#line 253 "inform7/Chapter 8/Traverse for Assertions.w"
void handle_sentence_with_primary_verb(parse_node *p) ;
#line 394 "inform7/Chapter 8/Traverse for Assertions.w"
void set_appearance(int wn) ;
#line 463 "inform7/Chapter 8/Traverse for Assertions.w"
inference_subject * Parser__Assertions__get_current_subject(void) ;
#line 467 "inform7/Chapter 8/Traverse for Assertions.w"
inference_subject * Parser__Assertions__get_current_object(void) ;
#line 471 "inform7/Chapter 8/Traverse for Assertions.w"
int Parser__Assertions__get_current_subject_plurality(void) ;
#line 490 "inform7/Chapter 8/Traverse for Assertions.w"
void Parser__Assertions__new_discussion(void) ;
#line 494 "inform7/Chapter 8/Traverse for Assertions.w"
void Parser__Assertions__change_discussion_topic(inference_subject *infsx, inference_subject *infsy, inference_subject *infsy_full) ;
#line 522 "inform7/Chapter 8/Traverse for Assertions.w"
void Parser__Assertions__subject_of_discussion_a_list(void) ;
#line 41 "inform7/Chapter 8/To Be and To Have.w"
void to_be(parse_node *pv) ;
#line 76 "inform7/Chapter 8/To Be and To Have.w"
void to_have(parse_node *pv) ;
#line 186 "inform7/Chapter 8/To Be and To Have.w"
void Parser__Assertions__make_assertion(parse_node *px, parse_node *py) ;
#line 245 "inform7/Chapter 8/To Be and To Have.w"
inference_subject * discussed_at_node(parse_node *pn) ;
#line 34 "inform7/Chapter 8/Refine Parse Tree.w"
void Parser__Nodes__noun_from_infs(parse_node *p, inference_subject *infs) ;
#line 39 "inform7/Chapter 8/Refine Parse Tree.w"
void Parser__Nodes__noun_from_value(parse_node *p, specification *spec) ;
#line 63 "inform7/Chapter 8/Refine Parse Tree.w"
void pn_noun_details_from_spec(parse_node *p, specification *spec) ;
#line 81 "inform7/Chapter 8/Refine Parse Tree.w"
void pn_make_COMMON_or_PROPER(parse_node *p, inference_subject *infs) ;
#line 93 "inform7/Chapter 8/Refine Parse Tree.w"
void Parser__Nodes__copy_noun_details(parse_node *to, parse_node *from) ;
#line 114 "inform7/Chapter 8/Refine Parse Tree.w"
void pn_make_adjective(parse_node *p, adjective_list_entry *ale, specification *spec) ;
#line 128 "inform7/Chapter 8/Refine Parse Tree.w"
void Parser__Nodes__coerce_adjectival_usage_to_noun(parse_node *leaf) ;
#line 148 "inform7/Chapter 8/Refine Parse Tree.w"
void Parser__Nodes__refine(parse_node *p, int creation_rule) ;
#line 168 "inform7/Chapter 8/Refine Parse Tree.w"
void refine_parse_tree_inner(parse_node *p, int creation_rule) ;
#line 670 "inform7/Chapter 8/Refine Parse Tree.w"
void Parser__Nodes__refine_from_docket(parse_node *p, specification *spec) ;
#line 791 "inform7/Chapter 8/Refine Parse Tree.w"
void perform_and_surgery(parse_node *p) ;
#line 838 "inform7/Chapter 8/Refine Parse Tree.w"
void perform_with_surgery(parse_node *p) ;
#line 871 "inform7/Chapter 8/Refine Parse Tree.w"
void perform_location_surgery(parse_node *p) ;
#line 910 "inform7/Chapter 8/Refine Parse Tree.w"
void perform_called_surgery(parse_node *p) ;
#line 38 "inform7/Chapter 8/The Creator.w"
int Parser__Assertions__consult_the_creator(parse_node *px, parse_node *py) ;
#line 146 "inform7/Chapter 8/The Creator.w"
binary_predicate * bp_of_subtree(parse_node *p) ;
#line 154 "inform7/Chapter 8/The Creator.w"
kind * kind_of_subtree(parse_node *p, parse_node **governing) ;
#line 252 "inform7/Chapter 8/The Creator.w"
void noun_creator(parse_node *p, kind *create_as, parse_node *governor) ;
#line 714 "inform7/Chapter 8/The Creator.w"
int Parser__Assertions__vet_name(int wording1, int wording2) ;
#line 742 "inform7/Chapter 8/The Creator.w"
void Parser__Assertions__convert_instance_to_nounphrase(parse_node *p, binary_predicate *hinge_relation) ;
#line 972 "inform7/Chapter 8/The Creator.w"
void Parser__Assertions__vet_name_for_noun(int wording1, int wording2) ;
#line 66 "inform7/Chapter 8/Make Assertions.w"
int which_assertion_case(parse_node *px, parse_node *py) ;
#line 91 "inform7/Chapter 8/Make Assertions.w"
void Parser__Assertions__make_assertion_recursive(parse_node *px, parse_node *py) ;
#line 97 "inform7/Chapter 8/Make Assertions.w"
void make_assertion_recursive_inner(parse_node *px, parse_node *py) ;
#line 1725 "inform7/Chapter 8/Make Assertions.w"
int convert_adjective_to_noun(parse_node *p) ;
#line 1738 "inform7/Chapter 8/Make Assertions.w"
void issue_value_equation_problem(parse_node *px, parse_node *py) ;
#line 1793 "inform7/Chapter 8/Make Assertions.w"
void instantiate_related_common_nouns(parse_node *p) ;
#line 1797 "inform7/Chapter 8/Make Assertions.w"
void instantiate_related_common_nouns_r(parse_node *from, parse_node *at) ;
#line 13 "inform7/Chapter 8/Property Knowledge.w"
void Parser__Assertions__initialise_global_variable(nonlocal_variable *q, specification *val) ;
#line 17 "inform7/Chapter 8/Property Knowledge.w"
void Parser__Assertions__verify_global_variable(nonlocal_variable *q) ;
#line 25 "inform7/Chapter 8/Property Knowledge.w"
void igv_dash(nonlocal_variable *q, specification *val, int verification_stage) ;
#line 100 "inform7/Chapter 8/Property Knowledge.w"
void Parser__Assertions__assert_property_value_from_property_subtree_infs(property *prn, inference_subject *owner, parse_node *val_subtree) ;
#line 106 "inform7/Chapter 8/Property Knowledge.w"
void Parser__Assertions__assert_property_list(parse_node *owner_subtree, parse_node *list_subtree) ;
#line 186 "inform7/Chapter 8/Property Knowledge.w"
specification * Parser__Assertions__property_value_from_property_subtree(property *prn, parse_node *py) ;
#line 16 "inform7/Chapter 8/Relation Knowledge.w"
void Parser__Assertions__assert_subtree_in_relationship(parse_node *value, parse_node *relationship_subtree) ;
#line 103 "inform7/Chapter 8/Relation Knowledge.w"
void assert_relation_between_subtrees(parse_node *px, binary_predicate *bp, parse_node *py) ;
#line 76 "inform7/Chapter 8/Assemblies.w"
void Parser__Assertions__Assemblies__initialise_assemblies_data(assemblies_data *ad) ;
#line 86 "inform7/Chapter 8/Assemblies.w"
void Parser__Assertions__Assemblies__name_object_after(inference_subject *infs, inference_subject *after, int w1, int w2) ;
#line 95 "inform7/Chapter 8/Assemblies.w"
inference_subject * Parser__Assertions__Assemblies__what_this_is_named_after(inference_subject *infs) ;
#line 100 "inform7/Chapter 8/Assemblies.w"
void Parser__Assertions__Assemblies__get_named_after_text(inference_subject *infs, int *n1, int *n2) ;
#line 119 "inform7/Chapter 8/Assemblies.w"
void Parser__Assertions__Assemblies__make_generalisation(parse_node *look_for, parse_node *what_to_make) ;
#line 204 "inform7/Chapter 8/Assemblies.w"
int subtree_mentions_kind(parse_node *subtree, inference_subject *k, int level) ;
#line 220 "inform7/Chapter 8/Assemblies.w"
void ensure_all_generalisations_made(inference_subject *k) ;
#line 234 "inform7/Chapter 8/Assemblies.w"
void Parser__Assertions__Assemblies__satisfies_generalisations(inference_subject *infs) ;
#line 302 "inform7/Chapter 8/Assemblies.w"
void satisfies_generalisation(inference_subject *infs, generalisation *g) ;
#line 45 "inform7/Chapter 8/Implications.w"
void Parser__Assertions__Implications__new(parse_node *px, parse_node *py) ;
#line 140 "inform7/Chapter 8/Implications.w"
void Parser__Assertions__Implications__consider_all(inference_subject *infs) ;
#line 167 "inform7/Chapter 8/Implications.w"
void set_possessed_flags(inference_subject *infs) ;
#line 215 "inform7/Chapter 8/Implications.w"
int check_implications_of(inference_subject *domain, inference_subject *candidate) ;
#line 67 "inform7/Chapter 8/Property Declarations.w"
void declare_property_can_be(parse_node *p) ;
#line 115 "inform7/Chapter 8/Property Declarations.w"
int list_length(parse_node *P) ;
#line 459 "inform7/Chapter 8/Property Declarations.w"
property * Parser__Assertions__recursively_declare_properties(parse_node *owner_ref, parse_node *p) ;
#line 530 "inform7/Chapter 8/Property Declarations.w"
void recursively_call_properties(parse_node *owner_ref, parse_node *kind_ref, parse_node *prn_ref) ;
#line 97 "inform7/Chapter 9/Articles and Pronouns.w"
void Text__Languages__remove_the(int *w1, int *w2) ;
#line 102 "inform7/Chapter 9/Articles and Pronouns.w"
void Text__Languages__remove_article(int *w1, int *w2) ;
#line 111 "inform7/Chapter 9/Determiners and Quantifiers.w"
quantifier * quant_new(char *op, int T, int is_comp, char *text) ;
#line 162 "inform7/Chapter 9/Determiners and Quantifiers.w"
void quants_negate_each_other(quantifier *qx, quantifier *qy) ;
#line 165 "inform7/Chapter 9/Determiners and Quantifiers.w"
quantifier * Semantics__Quantifiers__get_negation(quantifier *quant) ;
#line 172 "inform7/Chapter 9/Determiners and Quantifiers.w"
void Semantics__Quantifiers__log(quantifier *quant, int parameter) ;
#line 204 "inform7/Chapter 9/Determiners and Quantifiers.w"
void Semantics__Quantifiers__compile_test(OUTPUT_STREAM, quantifier *quant, int index, int quantification_parameter) ;
#line 240 "inform7/Chapter 9/Determiners and Quantifiers.w"
int Semantics__Quantifiers__is_now_assertable(quantifier *quant) ;
#line 250 "inform7/Chapter 9/Determiners and Quantifiers.w"
int Semantics__Quantifiers__can_be_used_in_assertions(quantifier *quant) ;
#line 281 "inform7/Chapter 9/Determiners and Quantifiers.w"
determiner * det_new(int not, int pr, int num, quantifier *quant, char *text) ;
#line 339 "inform7/Chapter 9/Determiners and Quantifiers.w"
int Semantics__Quantifiers__parse_against_text(int w1, int w2, int *which_P, quantifier **which_quant) ;
#line 402 "inform7/Chapter 9/Determiners and Quantifiers.w"
int det_parse_against_text(int x1, int w2, determiner *det, int *which_P) ;
#line 428 "inform7/Chapter 9/Determiners and Quantifiers.w"
void Semantics__Quantifiers__make_built_in(void) ;
#line 594 "inform7/Chapter 9/Determiners and Quantifiers.w"
int quant_requires_at_least_one_true_case(quantifier *quant, int parameter) ;
#line 339 "inform7/Chapter 9/Binary Predicates.w"
bp_term_details Semantics__BPs__Terms__new(inference_subject *infs) ;
#line 352 "inform7/Chapter 9/Binary Predicates.w"
bp_term_details Semantics__BPs__Terms__full_new(inference_subject *infs, kind *K, int c1, int c2, i6_schema *f) ;
#line 365 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Terms__set_domain(bp_term_details *bptd, kind *K) ;
#line 374 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Terms__set_function(bp_term_details *bptd, i6_schema *f) ;
#line 379 "inform7/Chapter 9/Binary Predicates.w"
i6_schema * Semantics__BPs__Terms__get_function(bp_term_details *bptd) ;
#line 387 "inform7/Chapter 9/Binary Predicates.w"
kind * Semantics__BPs__kind(binary_predicate *bp) ;
#line 399 "inform7/Chapter 9/Binary Predicates.w"
kind * bptd_kind(bp_term_details *bptd) ;
#line 408 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Terms__details_index(bp_term_details *bptd) ;
#line 421 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Terms__add_as_call_parameter(OUTPUT_STREAM, ph_stack_frame *phsf, bp_term_details bptd) ;
#line 435 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__set_index_details(binary_predicate *bp, char *left, char *right) ;
#line 463 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate * Semantics__BPs__make_equality(void) ;
#line 484 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate * Semantics__BPs__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 518 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate * Semantics__BPs__make_pair_sketchily(word_assemblage wa, int f) ;
#line 541 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate * make_single_BP(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 595 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Subjects__get_name_text(inference_subject *from, int *w1, int *w2) ;
#line 599 "inform7/Chapter 9/Binary Predicates.w"
general_pointer Semantics__BPs__Subjects__new_permission_granted(inference_subject *from) ;
#line 603 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Subjects__make_adj_const_domain(inference_subject *infs, instance *nc, property *prn) ;
#line 607 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Subjects__complete_model(inference_subject *infs) ;
#line 624 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Subjects__check_model(inference_subject *infs) ;
#line 632 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Subjects__write_element_of_condition(inference_subject *infs, char *cond) ;
#line 636 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__Subjects__compile_all(OUTPUT_STREAM) ;
#line 640 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Subjects__compile(OUTPUT_STREAM, inference_subject *infs) ;
#line 670 "inform7/Chapter 9/Binary Predicates.w"
void log_bp_term_details(bp_term_details *bptd, int i) ;
#line 680 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__log(binary_predicate *bp) ;
#line 712 "inform7/Chapter 9/Binary Predicates.w"
char * Semantics__BPs__get_log_name(binary_predicate *bp) ;
#line 719 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__get_form_of_relation(binary_predicate *bp) ;
#line 722 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__is_explicit_with_runtime_storage(binary_predicate *bp) ;
#line 728 "inform7/Chapter 9/Binary Predicates.w"
char * bp_form_to_text(binary_predicate *bp) ;
#line 746 "inform7/Chapter 9/Binary Predicates.w"
kind * Semantics__BPs__term_kind(binary_predicate *bp, int t) ;
#line 749 "inform7/Chapter 9/Binary Predicates.w"
i6_schema * Semantics__BPs__get_term_as_function_of_other(binary_predicate *bp, int t) ;
#line 756 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate * Semantics__BPs__get_reversal(binary_predicate *bp) ;
#line 759 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__is_the_wrong_way_round(binary_predicate *bp) ;
#line 767 "inform7/Chapter 9/Binary Predicates.w"
i6_schema * Semantics__BPs__get_test_function(binary_predicate *bp) ;
#line 770 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__can_be_made_true_at_runtime(binary_predicate *bp) ;
#line 784 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__allow_arbitrary_assertions(binary_predicate *bp) ;
#line 787 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__store_dynamically(binary_predicate *bp) ;
#line 790 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__relates_values_not_objects(binary_predicate *bp) ;
#line 793 "inform7/Chapter 9/Binary Predicates.w"
inference_subject * Semantics__BPs__as_subject(binary_predicate *bp) ;
#line 800 "inform7/Chapter 9/Binary Predicates.w"
property * Semantics__BPs__get_i6_storage_property(binary_predicate *bp) ;
#line 803 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__allows_function_simplification(binary_predicate *bp) ;
#line 806 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__mark_as_needed(binary_predicate *bp) ;
#line 813 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__set_comparison_details(binary_predicate *bp, int sign, property *prn) ;
#line 830 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__write_optimised_loop_schema(i6_schema *sch, binary_predicate *bp) ;
#line 873 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__make_built_in(void) ;
#line 890 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__make_built_in_further(void) ;
#line 910 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 930 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__assert(binary_predicate *bp, inference_subject *subj0, specification *spec0, inference_subject *subj1, specification *spec1) ;
#line 950 "inform7/Chapter 9/Binary Predicates.w"
i6_schema * Semantics__BPs__get_i6_schema(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 978 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 124 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__parse_new(parse_node *PN) ;
#line 151 "inform7/Chapter 9/Relations.w"
void parse_new_relation_further(parse_node *PN) ;
#line 736 "inform7/Chapter 9/Relations.w"
int parse_relation_term_type(int w1, int w2, kind **set_K, char *side) ;
#line 755 "inform7/Chapter 9/Relations.w"
int check_finite_range(kind *K) ;
#line 779 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__compile_defined_relation_constants(OUTPUT_STREAM) ;
#line 804 "inform7/Chapter 9/Relations.w"
void compile_relation_records(OUTPUT_STREAM) ;
#line 1089 "inform7/Chapter 9/Relations.w"
void write_rels_lookup(OUTPUT_STREAM, binary_predicate *bp, int t) ;
#line 1116 "inform7/Chapter 9/Relations.w"
void write_rels_lookup_list(OUTPUT_STREAM, binary_predicate *bp, int t) ;
#line 1138 "inform7/Chapter 9/Relations.w"
void write_rels_lookup_list_all(OUTPUT_STREAM, binary_predicate *bp, int t) ;
#line 1166 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__compile_default_relation(OUTPUT_STREAM, char *identifier, kind *K) ;
#line 1181 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__compile_blank_relation(OUTPUT_STREAM, kind *K) ;
#line 1202 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__relations_command(OUTPUT_STREAM) ;
#line 1230 "inform7/Chapter 9/Relations.w"
void begin_bit_stream(OUTPUT_STREAM) ;
#line 1234 "inform7/Chapter 9/Relations.w"
void compile_bit(OUTPUT_STREAM, int b) ;
#line 1244 "inform7/Chapter 9/Relations.w"
void end_bit_stream(OUTPUT_STREAM) ;
#line 1255 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__compile_vtov_storage(OUTPUT_STREAM, binary_predicate *bp) ;
#line 1362 "inform7/Chapter 9/Relations.w"
int infs_in_domain(inference_subject *infs, binary_predicate *bp, int index) ;
#line 1413 "inform7/Chapter 9/Relations.w"
int relation_range(binary_predicate *bp, int index) ;
#line 1427 "inform7/Chapter 9/Relations.w"
void allocate_index_storage(void) ;
#line 1432 "inform7/Chapter 9/Relations.w"
void set_relation_index(inference_subject *infs, int i, int v) ;
#line 1437 "inform7/Chapter 9/Relations.w"
int get_relation_index(inference_subject *infs, int i) ;
#line 1442 "inform7/Chapter 9/Relations.w"
void free_index_storage(void) ;
#line 1511 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__equivalence_relation_make_singleton_partitions(binary_predicate *bp, int domain_size) ;
#line 1551 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__equivalence_relation_merge_classes(binary_predicate *bp, int domain_size, int ix1, int ix2) ;
#line 1575 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__equivalence_relation_add_properties(binary_predicate *bp) ;
#line 1602 "inform7/Chapter 9/Relations.w"
int equivalence_relation_get_class(binary_predicate *bp, int ix) ;
#line 1621 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__check_1to1_relation(binary_predicate *bp) ;
#line 1686 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__compile_defined_relations(OUTPUT_STREAM) ;
#line 1783 "inform7/Chapter 9/Relations.w"
void Code__Frames__condition_routine(OUTPUT_STREAM, char *rname, int w1, int w2, bp_term_details par1, bp_term_details par2) ;
#line 1812 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__index_table(void) ;
#line 1862 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__index_for_verbs(binary_predicate *bp) ;
#line 14 "inform7/Chapter 9/Explicit Relations.w"
void Semantics__Relations__Explicit__create_initial_stock(void) ;
#line 16 "inform7/Chapter 9/Explicit Relations.w"
void Semantics__Relations__Explicit__create_second_stock(void) ;
#line 22 "inform7/Chapter 9/Explicit Relations.w"
int Semantics__Relations__Explicit__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 32 "inform7/Chapter 9/Explicit Relations.w"
int Semantics__Relations__Explicit__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 91 "inform7/Chapter 9/Explicit Relations.w"
void infer_property_based_relation(binary_predicate *relation, inference_subject *infs0, inference_subject *infs1) ;
#line 103 "inform7/Chapter 9/Explicit Relations.w"
int Semantics__Relations__Explicit__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 110 "inform7/Chapter 9/Explicit Relations.w"
int Semantics__Relations__Explicit__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 20 "inform7/Chapter 9/The Universal Relation.w"
void Semantics__Relations__Universal__create_initial_stock(void) ;
#line 37 "inform7/Chapter 9/The Universal Relation.w"
void Semantics__Relations__Universal__create_second_stock(void) ;
#line 44 "inform7/Chapter 9/The Universal Relation.w"
int Semantics__Relations__Universal__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 109 "inform7/Chapter 9/The Universal Relation.w"
int Semantics__Relations__Universal__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 120 "inform7/Chapter 9/The Universal Relation.w"
int Semantics__Relations__Universal__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 148 "inform7/Chapter 9/The Universal Relation.w"
int Semantics__Relations__Universal__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 84 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_usage * register_vu(word_assemblage wa, int negated, int tensed, binary_predicate *root, verb_conjugation *vc, int unexpected_upper_casing_used) ;
#line 103 "inform7/Chapter 9/Conjugation of Verbs.w"
int vu_foreign(verb_usage *vu) ;
#line 116 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_usage * find_vu(word_assemblage against) ;
#line 127 "inform7/Chapter 9/Conjugation of Verbs.w"
binary_predicate * Semantics__VerbUsage__get_meaning(verb_usage *vu) ;
#line 130 "inform7/Chapter 9/Conjugation of Verbs.w"
int Semantics__VerbUsage__get_tense_used(verb_usage *vu) ;
#line 133 "inform7/Chapter 9/Conjugation of Verbs.w"
int Semantics__VerbUsage__is_used_negatively(verb_usage *vu) ;
#line 144 "inform7/Chapter 9/Conjugation of Verbs.w"
preposition_usage * Semantics__PrepositionUsage__register(word_assemblage wa, int assumes_player, binary_predicate *root, int stroked, int unexpected_upper_casing_used) ;
#line 174 "inform7/Chapter 9/Conjugation of Verbs.w"
preposition_usage * find_pu(word_assemblage against) ;
#line 185 "inform7/Chapter 9/Conjugation of Verbs.w"
int Semantics__PrepositionUsage__implicitly_negates(preposition_usage *pu) ;
#line 189 "inform7/Chapter 9/Conjugation of Verbs.w"
binary_predicate * Semantics__PrepositionUsage__get_meaning(preposition_usage *pu) ;
#line 205 "inform7/Chapter 9/Conjugation of Verbs.w"
int parse_against_verb(int w1, int w2, verb_usage *vu) ;
#line 455 "inform7/Chapter 9/Conjugation of Verbs.w"
int parse_prep_against(int w1, int w2, preposition_usage *pu, int fill) ;
#line 508 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__VerbUsage__log(verb_usage *vu) ;
#line 515 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__PrepositionUsage__log(preposition_usage *pu) ;
#line 522 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__VerbUsage__log_all(void) ;
#line 540 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__VerbUsage__tabulate(lexicon_entry *lex, int tense, char *tensename) ;
#line 562 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__VerbUsage__tabulate_meaning(lexicon_entry *lex) ;
#line 603 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__VerbUsage__stock(void) ;
#line 632 "inform7/Chapter 9/Conjugation of Verbs.w"
void register_regular_verb(verb_conjugation *vc, binary_predicate *root, int unexpected_upper_casing_used) ;
#line 650 "inform7/Chapter 9/Conjugation of Verbs.w"
void register_main_forms_of_verb(verb_conjugation *vc, verb_tabulation *vt, binary_predicate *root, int unexpected_upper_casing_used) ;
#line 706 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__PrepositionUsage__register_comparative(int wn, binary_predicate *root) ;
#line 714 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__PrepositionUsage__register_same_property_as(binary_predicate *root) ;
#line 879 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__VerbUsage__parse_new(parse_node *PN) ;
#line 1150 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__ConjugateVerb_invoke(OUTPUT_STREAM, verb_conjugation *vc, verb_conjugation *modal, int negated) ;
#line 1175 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__ConjugateVerb_routine(OUTPUT_STREAM) ;
#line 1313 "inform7/Chapter 9/Conjugation of Verbs.w"
void conj_from_wa(OUTPUT_STREAM, word_assemblage *wa, verb_conjugation *vc, int mau) ;
#line 1343 "inform7/Chapter 9/Conjugation of Verbs.w"
int takes_contraction_form(word_assemblage *wa) ;
#line 1351 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_conjugation * Semantics__find_vc_by_infinitive(word_assemblage infinitive) ;
#line 181 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase * Semantics__Adjectives__Phrases__parse(int w1, int w2) ;
#line 190 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase * aph_from_word_range(int w1, int w2, natural_language *nl) ;
#line 219 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__get_text(adjectival_phrase *aph, int *w1, int *w2, int plural) ;
#line 232 "inform7/Chapter 9/Adjectives.w"
void declare_meaningless_adj(parse_node *p) ;
#line 242 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase * Semantics__Adjectives__Meanings__declare_textually(int w1, int w2) ;
#line 252 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__test_adjective(OUTPUT_STREAM, int w1, int w2) ;
#line 279 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase * Semantics__Adjectives__Meanings__declare(adjective_meaning *am, int w1, int w2) ;
#line 298 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase * Semantics__Adjectives__Meanings__get_aph(adjective_meaning *am) ;
#line 307 "inform7/Chapter 9/Adjectives.w"
void aph_sortrandom_meanings(adjectival_phrase *aph) ;
#line 312 "inform7/Chapter 9/Adjectives.w"
adjective_meaning * am_list_sort(adjective_meaning *unsorted_head) ;
#line 350 "inform7/Chapter 9/Adjectives.w"
adjective_meaning * aph_get_sorted_definition_list(adjectival_phrase *aph) ;
#line 357 "inform7/Chapter 9/Adjectives.w"
adjective_meaning * Semantics__Adjectives__first_meaning(adjectival_phrase *aph) ;
#line 365 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__log(adjectival_phrase *aph) ;
#line 376 "inform7/Chapter 9/Adjectives.w"
void aph_log_meanings(adjectival_phrase *aph) ;
#line 399 "inform7/Chapter 9/Adjectives.w"
adjective_meaning * Semantics__Adjectives__Meanings__new(int form, general_pointer details, int ix1, int ix2) ;
#line 434 "inform7/Chapter 9/Adjectives.w"
adjective_meaning * Semantics__Adjectives__Meanings__negate(adjective_meaning *am) ;
#line 463 "inform7/Chapter 9/Adjectives.w"
int Semantics__Adjectives__Meanings__get_form(adjective_meaning *am) ;
#line 491 "inform7/Chapter 9/Adjectives.w"
int domain_weak_match(kind *K1, kind *K2) ;
#line 501 "inform7/Chapter 9/Adjectives.w"
int domain_subj_compare(inference_subject *infs, adjective_meaning *am) ;
#line 530 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__set_domain_from_word_range(adjective_meaning *am, int w1, int w2) ;
#line 537 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__set_domain_from_instance(adjective_meaning *am, instance *I) ;
#line 554 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__set_domain_from_kind(adjective_meaning *am, kind *K) ;
#line 564 "inform7/Chapter 9/Adjectives.w"
kind * Semantics__Adjectives__Meanings__get_domain(adjective_meaning *am) ;
#line 569 "inform7/Chapter 9/Adjectives.w"
kind * Semantics__Adjectives__Meanings__get_domain_forcing(adjective_meaning *am) ;
#line 581 "inform7/Chapter 9/Adjectives.w"
void am_set_definition_domain(adjective_meaning *am, int early) ;
#line 683 "inform7/Chapter 9/Adjectives.w"
int compare_ams(adjective_meaning *am1, adjective_meaning *am2) ;
#line 770 "inform7/Chapter 9/Adjectives.w"
int Semantics__Adjectives__Phrases__applicable_to(adjectival_phrase *aph, kind *K) ;
#line 795 "inform7/Chapter 9/Adjectives.w"
instance * Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(adjectival_phrase *aph) ;
#line 803 "inform7/Chapter 9/Adjectives.w"
property * Semantics__Adjectives__Phrases__has_EORP_meaning(adjectival_phrase *aph) ;
#line 841 "inform7/Chapter 9/Adjectives.w"
int Semantics__Adjectives__Phrases__assert(adjectival_phrase *aph, kind *kind_domain, inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) ;
#line 903 "inform7/Chapter 9/Adjectives.w"
i6_schema * Semantics__Adjectives__Meanings__set_i6_schema(adjective_meaning *am, int T, int via_support) ;
#line 923 "inform7/Chapter 9/Adjectives.w"
i6_schema * Semantics__Adjectives__Phrases__get_i6_schema(adjectival_phrase *aph, kind *kind_domain, int T) ;
#line 968 "inform7/Chapter 9/Adjectives.w"
int Semantics__Adjectives__Phrases__write_adjective_test_routine(OUTPUT_STREAM, adjectival_phrase *aph) ;
#line 989 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__pass_task_to_support_routine(adjective_meaning *am, int T) ;
#line 998 "inform7/Chapter 9/Adjectives.w"
int Semantics__Adjectives__Meanings__get_ready_flag(adjective_meaning *am) ;
#line 1001 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__set_ready_flag(adjective_meaning *am) ;
#line 1012 "inform7/Chapter 9/Adjectives.w"
adjective_meaning * am_list_next_domain_kind(adjective_meaning *am, kind **K, int T) ;
#line 1028 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Phrases__compile_support_code(OUTPUT_STREAM) ;
#line 1130 "inform7/Chapter 9/Adjectives.w"
void am_list_compile(adjective_meaning *list_head, OUTPUT_STREAM, ph_stack_frame *phsf, kind *K, int T) ;
#line 1176 "inform7/Chapter 9/Adjectives.w"
adjective_meaning * Semantics__Adjectives__Meanings__parse(parse_node *q, int sense, int adj_name_w1, int adj_name_w2, int dom_name_w1, int dom_name_w2, int cond_w1, int cond_w2, int called_w1, int called_w2) ;
#line 1206 "inform7/Chapter 9/Adjectives.w"
void am_compiling_soon(adjective_meaning *am, int T) ;
#line 1234 "inform7/Chapter 9/Adjectives.w"
int am_compile(adjective_meaning *am, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 1278 "inform7/Chapter 9/Adjectives.w"
int am_assert(adjective_meaning *am, inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) ;
#line 1319 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__print_to_index(adjective_meaning *am) ;
#line 1385 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__agreements(OUTPUT_STREAM) ;
#line 1425 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__invoke(OUTPUT_STREAM, adjectival_phrase *aph) ;
#line 177 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * lp_new(kind *K, int spw1, int spw2) ;
#line 198 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_token lpt_new(int t, int nw) ;
#line 210 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_element lpe_new(int i, int r, int sgn) ;
#line 231 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * Semantics__Nouns__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 * lp_list_add_inner(literal_pattern *list_head, literal_pattern *new_lp) ;
#line 341 "inform7/Chapter 10/Literal Patterns.w"
int lp_precedes(literal_pattern *A, literal_pattern *B) ;
#line 358 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * get_benchmark(kind *K) ;
#line 370 "inform7/Chapter 10/Literal Patterns.w"
int Semantics__Nouns__LiteralPatterns__scale_factor(kind *K) ;
#line 381 "inform7/Chapter 10/Literal Patterns.w"
int at_optional_break_point(literal_pattern *lp, int ec, int tc) ;
#line 400 "inform7/Chapter 10/Literal Patterns.w"
kind * Semantics__Nouns__LiteralPatterns__match(literal_pattern *lp, int w1, int w2, int *found) ;
#line 684 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__gpr_locals(void) ;
#line 702 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__gpr(OUTPUT_STREAM, literal_pattern *lp) ;
#line 878 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__index_all(kind *K) ;
#line 951 "inform7/Chapter 10/Literal Patterns.w"
void index_lp_possibilities(literal_pattern *lp, literal_pattern *benchmark_lp) ;
#line 979 "inform7/Chapter 10/Literal Patterns.w"
void index_lp_possibility(literal_pattern *lp, literal_pattern *benchmark_lp) ;
#line 998 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__index_value(literal_pattern *lp_list, int v) ;
#line 1029 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__index_benchmark_value(kind *K) ;
#line 1043 "inform7/Chapter 10/Literal Patterns.w"
void lp_index_quantum_value(literal_pattern *lp, scaling_transformation sc) ;
#line 1053 "inform7/Chapter 10/Literal Patterns.w"
void lp_index_value_specific(literal_pattern *lp, double alt_value) ;
#line 1059 "inform7/Chapter 10/Literal Patterns.w"
void lp_index_value_specific_inner(literal_pattern *lp, int v, double real_v) ;
#line 1122 "inform7/Chapter 10/Literal Patterns.w"
char * leading_zero_prototype(int range) ;
#line 1138 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__printing_routine(OUTPUT_STREAM, literal_pattern *lp_list) ;
#line 1307 "inform7/Chapter 10/Literal Patterns.w"
void comment_use_of_lp(OUTPUT_STREAM, literal_pattern *lp) ;
#line 1318 "inform7/Chapter 10/Literal Patterns.w"
void log_lp_debugging_data(OUTPUT_STREAM, literal_pattern *lp) ;
#line 1343 "inform7/Chapter 10/Literal Patterns.w"
void new_literal_specification(parse_node *pn) ;
#line 1357 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * new_literal_specification_list(parse_node *p, parse_node *q, literal_pattern *lp_main) ;
#line 1386 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * new_literal_specification_inner(parse_node *p, parse_node *q, literal_pattern *owner) ;
#line 1920 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_name * new_lpn(int w1, int w2, literal_pattern_name *existing) ;
#line 1940 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__define_named_phrases(void) ;
#line 1999 "inform7/Chapter 10/Literal Patterns.w"
void define_packing_phrases(literal_pattern *lp, kind *K) ;
#line 44 "inform7/Chapter 10/Times of Day.w"
void Plugins__Times__start(void) ;
#line 51 "inform7/Chapter 10/Times of Day.w"
int times_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) ;
#line 61 "inform7/Chapter 10/Times of Day.w"
kind * Plugins__Times__kind(void) ;
#line 165 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning * Semantics__Nouns__ExcerptMeanings__new(unsigned int mc, unsigned int smc, general_pointer data) ;
#line 179 "inform7/Chapter 10/Excerpt Meanings.w"
unsigned int Semantics__Nouns__ExcerptMeanings__get_secondary_code(excerpt_meaning *em) ;
#line 184 "inform7/Chapter 10/Excerpt Meanings.w"
general_pointer Semantics__Nouns__ExcerptMeanings__data(excerpt_meaning *em) ;
#line 192 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__log_meaning_code(unsigned int mc) ;
#line 235 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__log(excerpt_meaning *em) ;
#line 251 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__log_all(void) ;
#line 282 "inform7/Chapter 10/Excerpt Meanings.w"
int Semantics__Nouns__ExcerptMeanings__hash_code(int w1, int w2) ;
#line 309 "inform7/Chapter 10/Excerpt Meanings.w"
void hash_code_from_token_list(excerpt_meaning *em) ;
#line 403 "inform7/Chapter 10/Excerpt Meanings.w"
void register_em(unsigned int meaning_code, excerpt_meaning *em) ;
#line 514 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning * Semantics__Nouns__ExcerptMeanings__register( unsigned int meaning_code, unsigned int secondary, int w1, int w2, general_pointer data) ;
#line 636 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning * Semantics__Nouns__ExcerptMeanings__register_assemblage( unsigned int meaning_code, unsigned int secondary, word_assemblage wa, general_pointer data) ;
#line 15 "inform7/Chapter 10/Unicode Translations.w"
void unicode_translates(parse_node *pn) ;
#line 99 "inform7/Chapter 10/Unicode Translations.w"
int Unicode_char_in_range(int cc) ;
#line 61 "inform7/Chapter 11/Nametags.w"
individual_name * add_to_nametag_and_reg(nametag *t, int w1, int w2, natural_language *foreign_language, int gender, int number, int options) ;
#line 91 "inform7/Chapter 11/Nametags.w"
nametag * Data__Nametags__new(int w1, int w2, general_pointer owner, int p, int options, unsigned int mc, natural_language *foreign_language, int gender) ;
#line 123 "inform7/Chapter 11/Nametags.w"
excerpt_meaning * register_nametag(int w1, int w2, nametag *t, natural_language *foreign_language) ;
#line 131 "inform7/Chapter 11/Nametags.w"
void Data__Nametags__log(nametag *t) ;
#line 152 "inform7/Chapter 11/Nametags.w"
void Data__Nametags__get_name(nametag *t, int *w1, int *w2, int plural_flag) ;
#line 156 "inform7/Chapter 11/Nametags.w"
void Data__Nametags__get_name_in_play(nametag *t, int *w1, int *w2, int plural_flag) ;
#line 160 "inform7/Chapter 11/Nametags.w"
void Data__Nametags__set_plural_name(nametag *t, int pw1, int pw2) ;
#line 164 "inform7/Chapter 11/Nametags.w"
int Data__Nametags__full_name_includes(nametag *t, vocabulary_entry *wd) ;
#line 178 "inform7/Chapter 11/Nametags.w"
general_pointer Data__Nametags__tag_holder(nametag *t) ;
#line 183 "inform7/Chapter 11/Nametags.w"
int Data__Nametags__priority(nametag *t) ;
#line 188 "inform7/Chapter 11/Nametags.w"
int Data__Nametags__range_number(nametag *t) ;
#line 193 "inform7/Chapter 11/Nametags.w"
void Data__Nametags__set_range_number(nametag *t, int r) ;
#line 198 "inform7/Chapter 11/Nametags.w"
int Data__Nametags__exactitude(nametag *t) ;
#line 204 "inform7/Chapter 11/Nametags.w"
excerpt_meaning * Data__Nametags__get_principal_meaning(nametag *t) ;
#line 208 "inform7/Chapter 11/Nametags.w"
name_resolution_data * Data__Nametags__name_resolution_data(nametag *t) ;
#line 219 "inform7/Chapter 11/Nametags.w"
char * Data__Nametags__identifier(nametag *t) ;
#line 224 "inform7/Chapter 11/Nametags.w"
void nametag_compose_identifier(nametag *t, char C, int N) ;
#line 235 "inform7/Chapter 11/Nametags.w"
void nametag_set_I6_representation(nametag *t, char *new) ;
#line 249 "inform7/Chapter 11/Nametags.w"
void Data__Nametags__name_all(void) ;
#line 293 "inform7/Chapter 11/Nametags.w"
nametag * Data__Nametags__disambiguate(meaning_list *ml, int priority) ;
#line 342 "inform7/Chapter 11/Nametags.w"
void nl_translates(parse_node *pn) ;
#line 85 "inform7/Chapter 11/Instances.w"
instance * Data__Instances__new(int w1, int w2, kind *K) ;
#line 185 "inform7/Chapter 11/Instances.w"
parse_node * Data__Instances__get_creating_sentence(instance *I) ;
#line 193 "inform7/Chapter 11/Instances.w"
source_file * Data__Instances__get_creating_file(instance *I) ;
#line 207 "inform7/Chapter 11/Instances.w"
void Data__Instances__make_kind_coincident(kind *K, property *P) ;
#line 221 "inform7/Chapter 11/Instances.w"
void Data__Instances__update_adjectival_forms(property *P) ;
#line 238 "inform7/Chapter 11/Instances.w"
void register_as_adjectival_constant(instance *I, property *P) ;
#line 249 "inform7/Chapter 11/Instances.w"
void Data__Instances__log(instance *I) ;
#line 263 "inform7/Chapter 11/Instances.w"
specification * Data__Instances__get_value(instance *I) ;
#line 273 "inform7/Chapter 11/Instances.w"
int Data__Instances__get_numerical_value(instance *I) ;
#line 277 "inform7/Chapter 11/Instances.w"
inference_subject * Data__Instances__as_subject(instance *I) ;
#line 285 "inform7/Chapter 11/Instances.w"
void Data__Instances__get_name(instance *I, int *w1, int *w2, int plural) ;
#line 290 "inform7/Chapter 11/Instances.w"
void Data__Instances__get_name_in_play(instance *I, int *w1, int *w2, int plural) ;
#line 295 "inform7/Chapter 11/Instances.w"
int Data__Instances__full_name_includes(instance *I, vocabulary_entry *wd) ;
#line 300 "inform7/Chapter 11/Instances.w"
nametag * Data__Instances__get_nametag(instance *I) ;
#line 304 "inform7/Chapter 11/Instances.w"
char * Data__Instances__identifier(instance *I) ;
#line 312 "inform7/Chapter 11/Instances.w"
void Data__Instances__write_name_for_index(OUTPUT_STREAM, instance *I) ;
#line 333 "inform7/Chapter 11/Instances.w"
instance * Data__Instances__parse_object(int w1, int w2) ;
#line 391 "inform7/Chapter 11/Instances.w"
kind * Data__Instances__kind(instance *I) ;
#line 397 "inform7/Chapter 11/Instances.w"
int Data__Instances__of_kind(instance *I, kind *match) ;
#line 408 "inform7/Chapter 11/Instances.w"
void Data__Instances__set_kind(instance *I, kind *new) ;
#line 460 "inform7/Chapter 11/Instances.w"
parse_node * Data__Instances__get_kind_set_sentence(instance *I) ;
#line 480 "inform7/Chapter 11/Instances.w"
int Data__Instances__count(kind *K) ;
#line 499 "inform7/Chapter 11/Instances.w"
void Data__Instances__set_connection(instance *I, general_pointer gp) ;
#line 503 "inform7/Chapter 11/Instances.w"
general_pointer Data__Instances__get_connection(instance *I) ;
#line 511 "inform7/Chapter 11/Instances.w"
void Data__Nametags__increment_indexing_count(instance *I) ;
#line 515 "inform7/Chapter 11/Instances.w"
int Data__Instances__indexed_yet(instance *I) ;
#line 523 "inform7/Chapter 11/Instances.w"
void Data__Instances__index_name(instance *I) ;
#line 542 "inform7/Chapter 11/Instances.w"
void Data__Instances__note_usage(instance *I, parse_node *NB) ;
#line 558 "inform7/Chapter 11/Instances.w"
void Data__Instances__index_usages(instance *I) ;
#line 582 "inform7/Chapter 11/Instances.w"
void Data__Instances__Subjects__get_name_text(inference_subject *from, int *w1, int *w2) ;
#line 587 "inform7/Chapter 11/Instances.w"
general_pointer Data__Instances__Subjects__new_permission_granted(inference_subject *from) ;
#line 592 "inform7/Chapter 11/Instances.w"
void Data__Instances__Subjects__complete_model(inference_subject *infs) ;
#line 595 "inform7/Chapter 11/Instances.w"
void Data__Instances__Subjects__check_model(inference_subject *infs) ;
#line 601 "inform7/Chapter 11/Instances.w"
void Data__Instances__Subjects__make_adj_const_domain(inference_subject *S, instance *I, property *P) ;
#line 610 "inform7/Chapter 11/Instances.w"
void Data__Instances__Subjects__write_element_of_condition(inference_subject *infs, char *cond) ;
#line 623 "inform7/Chapter 11/Instances.w"
int Data__Instances__Subjects__compile_all(OUTPUT_STREAM) ;
#line 635 "inform7/Chapter 11/Instances.w"
void Data__Instances__Subjects__compile(OUTPUT_STREAM, inference_subject *infs) ;
#line 658 "inform7/Chapter 11/Instances.w"
adjectival_phrase * Data__Instances__get_adjectival_phrase(instance *I) ;
#line 662 "inform7/Chapter 11/Instances.w"
adjective_meaning * Data__Instances__Adjectives__parse(parse_node *pn, int sense, int adj_name_w1, int adj_name_w2, int dom_name_w1, int dom_name_w2, int cond_w1, int cond_w2, int called_w1, int called_w2) ;
#line 668 "inform7/Chapter 11/Instances.w"
void Data__Instances__Adjectives__compiling_soon(adjective_meaning *am, instance *I, int T) ;
#line 671 "inform7/Chapter 11/Instances.w"
int Data__Instances__Adjectives__compile(instance *I, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 681 "inform7/Chapter 11/Instances.w"
int Data__Instances__Adjectives__assert(instance *I, inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) ;
#line 693 "inform7/Chapter 11/Instances.w"
int Data__Instances__Adjectives__index(instance *I) ;
#line 734 "inform7/Chapter 11/Instances.w"
void Data__Instances__make_adj_const_domain(instance *I, property *P, kind *set, instance *singleton) ;
#line 18 "inform7/Chapter 11/Index Physical World.w"
void Data__Objects__page_Kinds(void) ;
#line 49 "inform7/Chapter 11/Index Physical World.w"
void Data__Objects__page_World(void) ;
#line 173 "inform7/Chapter 11/Index Physical World.w"
void Data__Objects__index(instance *I, kind *K, int depth, int details) ;
#line 366 "inform7/Chapter 11/Index Physical World.w"
void Data__Objects__index_instances(kind *K, int depth) ;
#line 223 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__log_production(unsigned int production) ;
#line 305 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__log(meaning_list *ml) ;
#line 310 "inform7/Chapter 12/Meaning Lists.w"
void log_ml_recursively(meaning_list *ml, int num, int of, int gen) ;
#line 455 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * get_available_ml(int seeking_permanent_slot) ;
#line 511 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__finish_this_session(void) ;
#line 619 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__new(unsigned int code_number) ;
#line 626 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__new_permanent(unsigned int code_number) ;
#line 650 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__new_with_words(unsigned int code_number, int w1, int w2) ;
#line 659 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__from_nametag(nametag *nt) ;
#line 672 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__type_from_ID(int ID_number) ;
#line 681 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__type_from_kind(kind *K) ;
#line 692 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__determiner(quantifier *quant, int parameter, int w1, int w2) ;
#line 706 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__time(time_period tp) ;
#line 715 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__verb(verb_usage *vu) ;
#line 724 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__preposition(preposition_usage *pu) ;
#line 733 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__option(int opt_num) ;
#line 744 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__action(action_pattern *ap) ;
#line 750 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__pastaction(action_pattern *ap) ;
#line 759 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__say_verb(verb_conjugation *vc, int neg) ;
#line 769 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__say_modal_verb(verb_conjugation *vc) ;
#line 779 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__say_adjective(adjectival_phrase *aph) ;
#line 790 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__copy(meaning_list *ml_to, meaning_list *ml_from) ;
#line 806 "inform7/Chapter 12/Meaning Lists.w"
unsigned int Parser__SP__MeaningLists__production(meaning_list *ml) ;
#line 809 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__set_production(meaning_list *ml, unsigned int pr) ;
#line 816 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__right(meaning_list *ml) ;
#line 819 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__set_right(meaning_list *ml, meaning_list *ml2) ;
#line 822 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__down(meaning_list *ml) ;
#line 825 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__set_down(meaning_list *ml, meaning_list *ml2) ;
#line 832 "inform7/Chapter 12/Meaning Lists.w"
meaning_list * Parser__SP__MeaningLists__sideways(meaning_list *ml) ;
#line 835 "inform7/Chapter 12/Meaning Lists.w"
int Parser__SP__MeaningLists__match_score(meaning_list *ml) ;
#line 838 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__set_score(meaning_list *ml, int s) ;
#line 849 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__set_text(meaning_list *ml, int w1, int w2) ;
#line 854 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__get_text(meaning_list *ml, int *w1, int *w2) ;
#line 861 "inform7/Chapter 12/Meaning Lists.w"
excerpt_meaning * Parser__SP__MeaningLists__meaning(meaning_list *ml) ;
#line 864 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__set_meaning(meaning_list *ml, excerpt_meaning *em) ;
#line 871 "inform7/Chapter 12/Meaning Lists.w"
specification * Parser__SP__MeaningLists__get_attached_spec(meaning_list *ml) ;
#line 874 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__attach_spec(meaning_list *ml, specification *spec) ;
#line 882 "inform7/Chapter 12/Meaning Lists.w"
general_pointer Parser__SP__MeaningLists__get_attached_data(meaning_list *ml) ;
#line 885 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__attach_data(meaning_list *ml, general_pointer data) ;
#line 84 "inform7/Chapter 12/Parse Excerpts.w"
meaning_list * Parser__SP__parse_excerpt_maximal(unsigned int mc_bitmap, int w1, int w2) ;
#line 92 "inform7/Chapter 12/Parse Excerpts.w"
meaning_list * Parser__SP__parse_excerpt(unsigned int mc_bitmap, int w1, int w2) ;
#line 521 "inform7/Chapter 12/Parse Excerpts.w"
void Parser__SP__debug_parser_statistics(void) ;
#line 353 "inform7/Chapter 12/Parse Literals.w"
int ismultiplicationsign(char c) ;
#line 371 "inform7/Chapter 12/Parse Literals.w"
int construct_float(int signbit, double intv, double fracv, int expo) ;
#line 447 "inform7/Chapter 12/Parse Literals.w"
double ten_to_the(int expo) ;
#line 293 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list * join_adjlist(meaning_list *A, meaning_list *B) ;
#line 298 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list * make_adjlist(meaning_list *A, int w1, int w2) ;
#line 304 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list * negate_adjlist(meaning_list *A) ;
#line 322 "inform7/Chapter 12/Constants and Descriptions.w"
int adjlist_applies_to_kind(meaning_list *A, kind *K) ;
#line 174 "inform7/Chapter 12/Verbal and Relative Clauses.w"
meaning_list * verb_ml_subtree(unsigned int mc, verb_usage *vu, preposition_usage *pu, meaning_list *np) ;
#line 188 "inform7/Chapter 12/Verbal and Relative Clauses.w"
meaning_list * player_ml_subtree(void) ;
#line 204 "inform7/Chapter 12/Verbal and Relative Clauses.w"
void Parser__SP__correct_S_subtree_for_adjectives(meaning_list *ml) ;
#line 95 "inform7/Chapter 12/Meaning List Conversions.w"
specification * Parser__SP__Conversion__CMD_subtree_to_spec(meaning_list *ml) ;
#line 130 "inform7/Chapter 12/Meaning List Conversions.w"
specification * Parser__SP__Conversion__COND_subtree_to_spec(meaning_list *ml) ;
#line 158 "inform7/Chapter 12/Meaning List Conversions.w"
specification * Parser__SP__Conversion__TE_subtree_to_spec(meaning_list *ml) ;
#line 212 "inform7/Chapter 12/Meaning List Conversions.w"
specification * Parser__SP__Conversion__VAL_subtree_to_spec(meaning_list *ml) ;
#line 272 "inform7/Chapter 12/Meaning List Conversions.w"
specification * ACTION_subtree_to_spec(meaning_list *ml) ;
#line 281 "inform7/Chapter 12/Meaning List Conversions.w"
specification * AP_subtree_to_spec(meaning_list *ml) ;
#line 290 "inform7/Chapter 12/Meaning List Conversions.w"
specification * CASE_subtree_to_spec(meaning_list *ml) ;
#line 307 "inform7/Chapter 12/Meaning List Conversions.w"
specification * COND_AND_subtree_to_spec(meaning_list *ml) ;
#line 318 "inform7/Chapter 12/Meaning List Conversions.w"
specification * COND_OR_subtree_to_spec(meaning_list *ml) ;
#line 329 "inform7/Chapter 12/Meaning List Conversions.w"
specification * COND_NOT_subtree_to_spec(meaning_list *ml) ;
#line 342 "inform7/Chapter 12/Meaning List Conversions.w"
specification * COND_PAST_subtree_to_spec(meaning_list *ml) ;
#line 356 "inform7/Chapter 12/Meaning List Conversions.w"
specification * COND_PHRASE_subtree_to_spec(meaning_list *ml) ;
#line 368 "inform7/Chapter 12/Meaning List Conversions.w"
specification * Parser__SP__Conversion__DC_subtree_to_spec(meaning_list *ml, int construed_as_noun) ;
#line 442 "inform7/Chapter 12/Meaning List Conversions.w"
specification * DC_ADJS_subtree_to_spec(meaning_list *ml, int construed_as_noun) ;
#line 465 "inform7/Chapter 12/Meaning List Conversions.w"
specification * DC_NOUN_subtree_to_spec(meaning_list *ml) ;
#line 474 "inform7/Chapter 12/Meaning List Conversions.w"
specification * DC_ADJSNOUN_subtree_to_spec(meaning_list *ml) ;
#line 483 "inform7/Chapter 12/Meaning List Conversions.w"
specification * LITERAL_subtree_to_spec(meaning_list *ml) ;
#line 492 "inform7/Chapter 12/Meaning List Conversions.w"
specification * LOCAL_subtree_to_spec(meaning_list *ml) ;
#line 501 "inform7/Chapter 12/Meaning List Conversions.w"
specification * MEMBER_OF_subtree_to_spec(meaning_list *ml) ;
#line 516 "inform7/Chapter 12/Meaning List Conversions.w"
specification * NP_subtree_to_spec(meaning_list *ml) ;
#line 533 "inform7/Chapter 12/Meaning List Conversions.w"
specification * OPTION_subtree_to_spec(meaning_list *ml) ;
#line 542 "inform7/Chapter 12/Meaning List Conversions.w"
specification * OTHERWISE_subtree_to_spec(meaning_list *ml) ;
#line 551 "inform7/Chapter 12/Meaning List Conversions.w"
specification * PHRASE_subtree_to_spec(meaning_list *ml) ;
#line 560 "inform7/Chapter 12/Meaning List Conversions.w"
specification * SN_subtree_to_spec(meaning_list *ml) ;
#line 569 "inform7/Chapter 12/Meaning List Conversions.w"
specification * STV_subtree_to_spec(meaning_list *ml) ;
#line 578 "inform7/Chapter 12/Meaning List Conversions.w"
specification * SV_subtree_to_spec(meaning_list *ml) ;
#line 587 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TE_CALLED_subtree_to_spec(meaning_list *ml) ;
#line 600 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TE_EX_VAR_subtree_to_spec(meaning_list *ml) ;
#line 610 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TE_GL_VAR_subtree_to_spec(meaning_list *ml) ;
#line 620 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TE_NEW_VAR_subtree_to_spec(meaning_list *ml) ;
#line 630 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TE_VAR_subtree_to_spec(meaning_list *ml) ;
#line 640 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TR_subtree_to_spec(meaning_list *ml) ;
#line 657 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TR_CORR_subtree_to_spec(meaning_list *ml) ;
#line 672 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TR_ENTRY_subtree_to_spec(meaning_list *ml) ;
#line 697 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TR_IN_ROW_subtree_to_spec(meaning_list *ml) ;
#line 709 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TR_LISTED_IN_subtree_to_spec(meaning_list *ml) ;
#line 720 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TR_OF_IN_subtree_to_spec(meaning_list *ml) ;
#line 733 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TYPE_subtree_to_spec(meaning_list *ml) ;
#line 750 "inform7/Chapter 12/Meaning List Conversions.w"
specification * VAL_LIST_ENTRY_subtree_to_spec(meaning_list *ml) ;
#line 761 "inform7/Chapter 12/Meaning List Conversions.w"
specification * VAL_NOTHING_subtree_to_spec(meaning_list *ml) ;
#line 770 "inform7/Chapter 12/Meaning List Conversions.w"
specification * VAL_PAIR_subtree_to_spec(meaning_list *ml) ;
#line 783 "inform7/Chapter 12/Meaning List Conversions.w"
specification * VAL_PROP_OF_subtree_to_spec(meaning_list *ml) ;
#line 809 "inform7/Chapter 12/Meaning List Conversions.w"
specification * VALUE_PHRASE_subtree_to_spec(meaning_list *ml) ;
#line 818 "inform7/Chapter 12/Meaning List Conversions.w"
specification * VAL_RESPONSE_subtree_to_spec(meaning_list *ml) ;
#line 844 "inform7/Chapter 12/Meaning List Conversions.w"
specification * ACTION_NAME_SMC_to_spec(meaning_list *ml) ;
#line 851 "inform7/Chapter 12/Meaning List Conversions.w"
specification * ACTIVITY_MC_to_spec(meaning_list *ml) ;
#line 858 "inform7/Chapter 12/Meaning List Conversions.w"
specification * EQUATION_MC_to_spec(meaning_list *ml) ;
#line 883 "inform7/Chapter 12/Meaning List Conversions.w"
specification * PROPERTY_MC_to_spec(meaning_list *ml) ;
#line 896 "inform7/Chapter 12/Meaning List Conversions.w"
specification * NAMED_CONSTANT_MC_to_spec(meaning_list *ml) ;
#line 903 "inform7/Chapter 12/Meaning List Conversions.w"
specification * PHRASE_CONSTANT_MC_to_spec(meaning_list *ml) ;
#line 910 "inform7/Chapter 12/Meaning List Conversions.w"
specification * RELATION_SMC_to_spec(meaning_list *ml) ;
#line 917 "inform7/Chapter 12/Meaning List Conversions.w"
specification * RULE_MC_to_spec(meaning_list *ml) ;
#line 924 "inform7/Chapter 12/Meaning List Conversions.w"
specification * RULE_SMC_to_spec(meaning_list *ml) ;
#line 931 "inform7/Chapter 12/Meaning List Conversions.w"
specification * RULEBOOK_MC_to_spec(meaning_list *ml) ;
#line 938 "inform7/Chapter 12/Meaning List Conversions.w"
specification * RULE_OUTCOME_SMC_to_spec(meaning_list *ml, int as_value) ;
#line 947 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TABLE_MC_to_spec(meaning_list *ml) ;
#line 954 "inform7/Chapter 12/Meaning List Conversions.w"
specification * TABLE_COLUMN_MC_to_spec(meaning_list *ml) ;
#line 961 "inform7/Chapter 12/Meaning List Conversions.w"
specification * USE_OPTION_SMC_to_spec(meaning_list *ml) ;
#line 968 "inform7/Chapter 12/Meaning List Conversions.w"
specification * VARIABLE_MC_to_spec(meaning_list *ml) ;
#line 975 "inform7/Chapter 12/Meaning List Conversions.w"
specification * NAMETAG_MC_to_spec(meaning_list *ml) ;
#line 990 "inform7/Chapter 12/Meaning List Conversions.w"
kind * police_te(meaning_list *ml) ;
#line 1061 "inform7/Chapter 12/Meaning List Conversions.w"
specification * general_phrase_to_spec(meaning_list *ml) ;
#line 1236 "inform7/Chapter 12/Meaning List Conversions.w"
specification * qualified_noun_to_spec(meaning_list *adjlist, meaning_list *noun) ;
#line 1309 "inform7/Chapter 12/Meaning List Conversions.w"
adjective_list_entry * adj_to_adjective_list_entry(meaning_list *ml) ;
#line 1332 "inform7/Chapter 12/Meaning List Conversions.w"
specification * general_sentence_to_spec(meaning_list *ml) ;
#line 1444 "inform7/Chapter 12/Meaning List Conversions.w"
void s_subtree_accumulate_headword(specification *spec, meaning_list *s_ml) ;
#line 92 "inform7/Chapter 13/Terms.w"
pcalc_term Calculus__Terms__new_variable(int v) ;
#line 99 "inform7/Chapter 13/Terms.w"
pcalc_term Calculus__Terms__new_constant(specification *c) ;
#line 105 "inform7/Chapter 13/Terms.w"
pcalc_term Calculus__Terms__new_function(binary_predicate *bp, pcalc_term ptof, int t) ;
#line 149 "inform7/Chapter 13/Terms.w"
specification * Calculus__Terms__constant_underlying(pcalc_term *t) ;
#line 155 "inform7/Chapter 13/Terms.w"
int Calculus__Terms__variable_underlying(pcalc_term *t) ;
#line 173 "inform7/Chapter 13/Terms.w"
pcalc_term Calculus__Terms__adj_to_noun_conversion(adjective_list_entry *tr) ;
#line 185 "inform7/Chapter 13/Terms.w"
adjective_list_entry * Calculus__Terms__noun_to_adj_conversion(pcalc_term pt) ;
#line 206 "inform7/Chapter 13/Terms.w"
void Calculus__Terms__log(pcalc_term *pt) ;
#line 84 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__element_get_group(int element) ;
#line 98 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__element_get_match(int element) ;
#line 112 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__new(int element) ;
#line 144 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__QUANTIFIER_new(quantifier *quant, int v, int parameter) ;
#line 156 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_quantifier(pcalc_prop *prop) ;
#line 161 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_existence_quantifier(pcalc_prop *prop) ;
#line 168 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_nonexistence_quantifier(pcalc_prop *prop) ;
#line 175 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_forall_quantifier(pcalc_prop *prop) ;
#line 182 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_notall_quantifier(pcalc_prop *prop) ;
#line 189 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_for_all_x(pcalc_prop *prop) ;
#line 197 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_now_assertable_quantifier(pcalc_prop *prop) ;
#line 206 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__EVERYWHERE_new(pcalc_term pt) ;
#line 216 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__NOWHERE_new(pcalc_term pt) ;
#line 226 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__HERE_new(pcalc_term pt) ;
#line 236 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__ISAKIND_new(pcalc_term pt, kind *K) ;
#line 247 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__ISAVAR_new(pcalc_term pt) ;
#line 257 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__ISACONST_new(pcalc_term pt) ;
#line 279 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__CALLED_new(int w1, int w2, pcalc_term pt, kind *K) ;
#line 288 "inform7/Chapter 13/Atomic Propositions.w"
void Calculus__Atoms__CALLED_get_name(pcalc_prop *prop, int *w1, int *w2) ;
#line 318 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__KIND_new(kind *K, pcalc_term pt) ;
#line 326 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__KIND_new_composited(kind *K, pcalc_term pt) ;
#line 335 "inform7/Chapter 13/Atomic Propositions.w"
kind * Calculus__Atoms__get_asserted_kind(pcalc_prop *prop) ;
#line 340 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_composited(pcalc_prop *prop) ;
#line 345 "inform7/Chapter 13/Atomic Propositions.w"
void Calculus__Atoms__set_composited(pcalc_prop *prop, int state) ;
#line 352 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_unarticled(pcalc_prop *prop) ;
#line 357 "inform7/Chapter 13/Atomic Propositions.w"
void Calculus__Atoms__set_unarticled(pcalc_prop *prop, int state) ;
#line 366 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__unary_PREDICATE_from_aph(adjectival_phrase *aph, int negated) ;
#line 378 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__binary_PREDICATE_new(binary_predicate *bp, pcalc_term pt1, pcalc_term pt2) ;
#line 387 "inform7/Chapter 13/Atomic Propositions.w"
binary_predicate * Calculus__Atoms__is_binary_predicate(pcalc_prop *prop) ;
#line 394 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_equality_predicate(pcalc_prop *prop) ;
#line 403 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__prop_x_is_constant(specification *spec) ;
#line 411 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_term * Calculus__Atoms__is_x_equals(pcalc_prop *prop) ;
#line 420 "inform7/Chapter 13/Atomic Propositions.w"
char * Calculus__Atoms__validate(pcalc_prop *prop) ;
#line 445 "inform7/Chapter 13/Atomic Propositions.w"
void Calculus__Atoms__log(pcalc_prop *prop) ;
#line 141 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__implied_conjunction_between(pcalc_prop *p1, pcalc_prop *p2) ;
#line 154 "inform7/Chapter 13/Propositions.w"
char * debugging_log_text_between(pcalc_prop *p1, pcalc_prop *p2) ;
#line 172 "inform7/Chapter 13/Propositions.w"
void Calculus__Propositions__log(pcalc_prop *prop) ;
#line 234 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__is_syntactically_valid(pcalc_prop *prop) ;
#line 276 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__copy(pcalc_prop *original) ;
#line 294 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__concatenate(pcalc_prop *existing_body, pcalc_prop *tail) ;
#line 305 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__conjoin(pcalc_prop *existing_body, pcalc_prop *tail) ;
#line 316 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__insert_atom(pcalc_prop *prop, pcalc_prop *position, pcalc_prop *new_atom) ;
#line 332 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__delete_atom(pcalc_prop *prop, pcalc_prop *position) ;
#line 350 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__length(pcalc_prop *prop) ;
#line 378 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__match(pcalc_prop *prop, int c, ...) ;
#line 404 "inform7/Chapter 13/Propositions.w"
pcalc_prop * prop_seek_atom(pcalc_prop *prop, int atom_req, int arity_req) ;
#line 416 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__contains_binary_predicate(pcalc_prop *prop) ;
#line 420 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__contains_quantifier(pcalc_prop *prop) ;
#line 424 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__composited_kind(pcalc_prop *prop) ;
#line 430 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__contains_nonexistence_quantifier(pcalc_prop *prop) ;
#line 439 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__contains_callings(pcalc_prop *prop) ;
#line 447 "inform7/Chapter 13/Propositions.w"
kind * Calculus__Propositions__describes_kind(pcalc_prop *prop) ;
#line 466 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__contains_adjective(pcalc_prop *prop) ;
#line 483 "inform7/Chapter 13/Propositions.w"
pcalc_term Calculus__Propositions__get_first_cited_term(pcalc_prop *prop) ;
#line 499 "inform7/Chapter 13/Propositions.w"
pcalc_term Calculus__Propositions__convert_adj_to_noun(pcalc_prop *prop) ;
#line 527 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__is_a_group(pcalc_prop *prop, int governing) ;
#line 543 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__remove_topmost_group(pcalc_prop *prop) ;
#line 558 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__unnegate(pcalc_prop *prop) ;
#line 568 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__ungroup_after(pcalc_prop *prop, pcalc_prop *position, pcalc_prop **last) ;
#line 603 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__trim_universal_quantifier(pcalc_prop *prop) ;
#line 616 "inform7/Chapter 13/Propositions.w"
pcalc_prop * Calculus__Propositions__remove_final_close_domain(pcalc_prop *prop, int *move_domain) ;
#line 78 "inform7/Chapter 13/Binding and Substitution.w"
void Calculus__Variables__determine_status(pcalc_prop *prop, int *var_states, int *valid) ;
#line 115 "inform7/Chapter 13/Binding and Substitution.w"
int Calculus__Propositions__is_well_formed(pcalc_prop *prop) ;
#line 126 "inform7/Chapter 13/Binding and Substitution.w"
int Calculus__Variables__status(pcalc_prop *prop, int v) ;
#line 136 "inform7/Chapter 13/Binding and Substitution.w"
int Calculus__Variables__number_free(pcalc_prop *prop) ;
#line 149 "inform7/Chapter 13/Binding and Substitution.w"
int Calculus__Variables__find_unused(pcalc_prop *prop) ;
#line 167 "inform7/Chapter 13/Binding and Substitution.w"
void vars_map(pcalc_prop *prop, int *renumber_map, pcalc_term *preserving) ;
#line 178 "inform7/Chapter 13/Binding and Substitution.w"
void term_map(pcalc_term *pt, int *renumber_map) ;
#line 193 "inform7/Chapter 13/Binding and Substitution.w"
void Calculus__Variables__renumber(pcalc_prop *prop, pcalc_term *preserving) ;
#line 231 "inform7/Chapter 13/Binding and Substitution.w"
int Calculus__Variables__renumber_bound(pcalc_prop *prop, pcalc_prop *not_to_overlap, int query) ;
#line 274 "inform7/Chapter 13/Binding and Substitution.w"
pcalc_prop * Calculus__Variables__bind_existential(pcalc_prop *prop, pcalc_term *preserving) ;
#line 295 "inform7/Chapter 13/Binding and Substitution.w"
int substitute_v_in_term(pcalc_term *pt, int v, pcalc_term *t) ;
#line 301 "inform7/Chapter 13/Binding and Substitution.w"
void Calculus__Propositions__substitute_nothing_in_term(pcalc_term *pt, pcalc_term *t) ;
#line 306 "inform7/Chapter 13/Binding and Substitution.w"
void Calculus__Propositions__substitute_term_in_term(pcalc_term *pt, pcalc_term *t) ;
#line 331 "inform7/Chapter 13/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 13/Binding and Substitution.w"
kind * Calculus__Variables__kind_of_variable_0(pcalc_prop *prop) ;
#line 413 "inform7/Chapter 13/Binding and Substitution.w"
pcalc_prop * Calculus__Propositions__substitute_var_0_in(pcalc_prop *prop, specification *spec) ;
#line 421 "inform7/Chapter 13/Binding and Substitution.w"
kind * Calculus__Variables__infer_kind_of_variable_0(pcalc_prop *prop) ;
#line 49 "inform7/Chapter 13/Propositional Form.w"
pcalc_prop * Calculus__Propositions__from_spec(specification *spec, int quantify) ;
#line 18 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_make_a_kind(kind *K) ;
#line 22 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_make_a_var(void) ;
#line 26 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_make_a_const(void) ;
#line 30 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_create_something(kind *K, int w1, int w2) ;
#line 44 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * prop_to_set_kind(instance *I, kind *k) ;
#line 48 "inform7/Chapter 13/Tree Conversions.w"
void Calculus__Propositions__assert_kind_of_object(instance *I, kind *k) ;
#line 53 "inform7/Chapter 13/Tree Conversions.w"
void Calculus__Propositions__assert_kind_of_subject(inference_subject *inst, inference_subject *new, pcalc_prop *subject_to) ;
#line 64 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_set_simple_relation(binary_predicate *bp, instance *I) ;
#line 72 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_set_relation(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 88 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_provide_property(property *prn) ;
#line 93 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_set_property(property *prn, specification *val) ;
#line 103 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_put_everywhere(void) ;
#line 107 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_put_nowhere(void) ;
#line 111 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__to_put_here(void) ;
#line 120 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__from_property_subtree(property *prn, parse_node *py) ;
#line 130 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__from_property_list(parse_node *p, kind *K) ;
#line 33 "inform7/Chapter 13/Sentence Conversions.w"
pcalc_prop * Parser__SP__Conversion__S_subtree(meaning_list *ml, pcalc_term *subject_of_sentence) ;
#line 485 "inform7/Chapter 13/Sentence Conversions.w"
pcalc_prop * NP_subtree_to_proposition(pcalc_term *subject_of_NP, meaning_list *ml, kind *K) ;
#line 48 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__nothing_constant(pcalc_prop *prop, int *changed) ;
#line 163 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__use_listed_in(pcalc_prop *prop, int *changed) ;
#line 216 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__negated_determiners_nonex(pcalc_prop *prop, int *changed) ;
#line 220 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__negated_determiners(pcalc_prop *prop, int *changed, int negate_existence_too) ;
#line 261 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * prop_ungroup_and_negate_determiner(pcalc_prop *prop, pcalc_prop *after, int add_domain_brackets) ;
#line 303 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__negated_satisfiable(pcalc_prop *prop, int *changed) ;
#line 353 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__make_kinds_of_value_explicit(pcalc_prop *prop, int *changed) ;
#line 383 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__redundant_kinds(pcalc_prop *prop, int *changed) ;
#line 403 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * simp_redundant_kinds_dash(pcalc_prop *prop, pcalc_prop *start_group, int start_level, int *changed) ;
#line 671 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__turn_right_way_round(pcalc_prop *prop, int *changed) ;
#line 711 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__region_containment(pcalc_prop *prop, int *changed) ;
#line 763 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__reduce_predicates(pcalc_prop *prop, int *changed) ;
#line 795 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__eliminate_redundant_variables(pcalc_prop *prop, int *changed) ;
#line 927 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__not_related_to_something(pcalc_prop *prop, int *changed) ;
#line 974 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__convert_gerunds(pcalc_prop *prop, int *changed) ;
#line 1016 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__eliminate_to_have(pcalc_prop *prop, int *changed) ;
#line 1061 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * prop_substitute_prop_cons(pcalc_prop *prop, property *prn, specification *po_spec, int *count, pcalc_prop *not_this) ;
#line 1108 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__is_all_rooms(pcalc_prop *prop, int *changed) ;
#line 1175 "inform7/Chapter 13/Simplifications.w"
pcalc_prop * Calculus__Simplifications__everywhere_and_nowhere(pcalc_prop *prop, int *changed) ;
#line 53 "inform7/Chapter 13/Type Check Propositions.w"
tc_problem_kit Calculus__Propositions__tc_no_problem_reporting(void) ;
#line 59 "inform7/Chapter 13/Type Check Propositions.w"
tc_problem_kit Calculus__Propositions__tc_problem_reporting(int w1, int w2, char *intent) ;
#line 69 "inform7/Chapter 13/Type Check Propositions.w"
tc_problem_kit Calculus__Propositions__tc_problem_logging(void) ;
#line 84 "inform7/Chapter 13/Type Check Propositions.w"
int Calculus__Propositions__type_check(pcalc_prop *prop, tc_problem_kit tck_s) ;
#line 395 "inform7/Chapter 13/Type Check Propositions.w"
kind * kind_of_term(pcalc_term *pt, variable_type_assignment *vta, tc_problem_kit *tck) ;
#line 410 "inform7/Chapter 13/Type Check Propositions.w"
kind * kind_of_term_inner(pcalc_term *pt, variable_type_assignment *vta, tc_problem_kit *tck) ;
#line 441 "inform7/Chapter 13/Type Check Propositions.w"
kind * approximate_argument_kind(binary_predicate *bp, int i) ;
#line 453 "inform7/Chapter 13/Type Check Propositions.w"
int type_check_unary_predicate(pcalc_prop *pl, variable_type_assignment *vta, tc_problem_kit *tck) ;
#line 483 "inform7/Chapter 13/Type Check Propositions.w"
int type_check_binary_predicate(pcalc_prop *pl, variable_type_assignment *vta, tc_problem_kit *tck) ;
#line 561 "inform7/Chapter 13/Type Check Propositions.w"
void Calculus__Propositions__issue_bp_typecheck_error(binary_predicate *bp, kind *t0, kind *t1, tc_problem_kit *tck) ;
#line 571 "inform7/Chapter 13/Type Check Propositions.w"
void issue_kind_typecheck_error(kind *actually_find, kind *need_to_find, tc_problem_kit *tck, pcalc_prop *ka) ;
#line 20 "inform7/Chapter 14/The Equality Relation.w"
void Calculus__Relations__Equality__create_initial_stock(void) ;
#line 33 "inform7/Chapter 14/The Equality Relation.w"
void Calculus__Relations__Equality__create_second_stock(void) ;
#line 41 "inform7/Chapter 14/The Equality Relation.w"
int Calculus__Relations__Equality__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 104 "inform7/Chapter 14/The Equality Relation.w"
int both_terms_of_same_construction(kind *k0, kind *k1, kind_constructor *cons) ;
#line 115 "inform7/Chapter 14/The Equality Relation.w"
int Calculus__Relations__Equality__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 169 "inform7/Chapter 14/The Equality Relation.w"
int Calculus__Relations__Equality__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 332 "inform7/Chapter 14/The Equality Relation.w"
int Calculus__Relations__Equality__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 32 "inform7/Chapter 14/Quasinumeric Relations.w"
void Calculus__Relations__Quasinumeric__create_initial_stock(void) ;
#line 68 "inform7/Chapter 14/Quasinumeric Relations.w"
void Calculus__Relations__Quasinumeric__create_second_stock(void) ;
#line 74 "inform7/Chapter 14/Quasinumeric Relations.w"
int Calculus__Relations__Quasinumeric__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 94 "inform7/Chapter 14/Quasinumeric Relations.w"
int Calculus__Relations__Quasinumeric__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 106 "inform7/Chapter 14/Quasinumeric Relations.w"
int Calculus__Relations__Quasinumeric__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 135 "inform7/Chapter 14/Quasinumeric Relations.w"
int Calculus__Relations__Quasinumeric__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 88 "inform7/Chapter 14/Assert Propositions.w"
void Calculus__Propositions__assert_true(pcalc_prop *prop, int certitude) ;
#line 92 "inform7/Chapter 14/Assert Propositions.w"
void Calculus__Propositions__assert_true_about(pcalc_prop *prop, inference_subject *infs, int certitude) ;
#line 117 "inform7/Chapter 14/Assert Propositions.w"
void prop_true_in_world_model_inner(pcalc_prop *prop, inference_subject *subject, int certainty) ;
#line 166 "inform7/Chapter 14/Assert Propositions.w"
void prop_true_in_model(pcalc_prop *prop) ;
#line 599 "inform7/Chapter 14/Assert Propositions.w"
void cautiously_set_kind(inference_subject *inst, kind *k) ;
#line 621 "inform7/Chapter 14/Assert Propositions.w"
specification * spec_of_term(pcalc_term pt) ;
#line 642 "inform7/Chapter 14/Assert Propositions.w"
inference_subject * subject_of_term(pcalc_term pt) ;
#line 673 "inform7/Chapter 14/Assert Propositions.w"
int Calculus__Propositions__testable_at_compile_time(pcalc_prop *prop) ;
#line 701 "inform7/Chapter 14/Assert Propositions.w"
int Calculus__Propositions__test_at_compile_time(pcalc_prop *prop, inference_subject *about) ;
#line 75 "inform7/Chapter 14/I6 Schemas.w"
i6_schema * Code__Schemas__new(char *fmt, ...) ;
#line 89 "inform7/Chapter 14/I6 Schemas.w"
void Code__Schemas__modify(i6_schema *sch, char *fmt, ...) ;
#line 101 "inform7/Chapter 14/I6 Schemas.w"
void Code__Schemas__append(i6_schema *sch, char *fmt, ...) ;
#line 153 "inform7/Chapter 14/I6 Schemas.w"
int Code__Schemas__empty(i6_schema *sch) ;
#line 164 "inform7/Chapter 14/I6 Schemas.w"
void Code__Schemas__expand(i6_schema *sch, OUTPUT_STREAM, pcalc_term *pt1, pcalc_term *pt2) ;
#line 178 "inform7/Chapter 14/I6 Schemas.w"
void Code__Schemas__expand_textual(i6_schema *sch, OUTPUT_STREAM, char *str1, char *str2) ;
#line 192 "inform7/Chapter 14/I6 Schemas.w"
void sch_expand_inner(i6_schema *sch, OUTPUT_STREAM, pcalc_term *pt1, char *str1, pcalc_term *pt2, char *str2) ;
#line 307 "inform7/Chapter 14/I6 Schemas.w"
void 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 349 "inform7/Chapter 14/I6 Schemas.w"
void sch_type_parameter(pcalc_term *pt) ;
#line 357 "inform7/Chapter 14/I6 Schemas.w"
void Code__Schemas__log(i6_schema *sch) ;
#line 362 "inform7/Chapter 14/I6 Schemas.w"
void Code__Schemas__log_applied(i6_schema *sch, pcalc_term *pt1) ;
#line 61 "inform7/Chapter 14/Compile Atoms.w"
void Calculus__Atoms__compile(OUTPUT_STREAM, int task, pcalc_prop *pl, int with_semicolon) ;
#line 145 "inform7/Chapter 14/Compile Atoms.w"
annotated_i6_schema i6_schema_of_atom(i6_schema *sch, pcalc_prop *pl, int task) ;
#line 329 "inform7/Chapter 14/Compile Atoms.w"
int atom_involves_action_variables(pcalc_prop *pl) ;
#line 341 "inform7/Chapter 14/Compile Atoms.w"
annotated_i6_schema Calculus__Atoms__blank_asch(void) ;
#line 53 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__allow_no_further_deferrals(void) ;
#line 61 "inform7/Chapter 14/Deciding to Defer.w"
pcalc_prop_deferral * new_deferred_proposition(pcalc_prop *prop, int reason) ;
#line 79 "inform7/Chapter 14/Deciding to Defer.w"
pcalc_prop_deferral * defer_loop_domain(pcalc_prop *prop) ;
#line 93 "inform7/Chapter 14/Deciding to Defer.w"
int Calculus__Deferrals__compile_deferred_description_test(specification *spec) ;
#line 118 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_test_of_proposition(OUTPUT_STREAM, specification *substitution, pcalc_prop *prop) ;
#line 232 "inform7/Chapter 14/Deciding to Defer.w"
void retrieve_callings(OUTPUT_STREAM, pcalc_prop *prop, int condition_context) ;
#line 258 "inform7/Chapter 14/Deciding to Defer.w"
void prepare_to_retrieve_callings(OUTPUT_STREAM, pcalc_prop *prop, int condition_context) ;
#line 276 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_test_if_var_matches_description(OUTPUT_STREAM, specification *var, specification *matches) ;
#line 321 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_now_proposition(OUTPUT_STREAM, pcalc_prop *prop, int with_semicolon) ;
#line 421 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_multiple_use_proposition(OUTPUT_STREAM, specification *spec, kind *K) ;
#line 491 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_number_of_S(OUTPUT_STREAM, specification *spec) ;
#line 506 "inform7/Chapter 14/Deciding to Defer.w"
int spec_is_variable_of_kind_description(specification *spec) ;
#line 513 "inform7/Chapter 14/Deciding to Defer.w"
void compile_call_to_deferred_desc(OUTPUT_STREAM, pcalc_prop *prop, int reason, general_pointer data, kind *K) ;
#line 535 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_list_of_S(OUTPUT_STREAM, specification *spec, kind *K) ;
#line 554 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_random_of_S(OUTPUT_STREAM, specification *spec) ;
#line 591 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_total_of_S(OUTPUT_STREAM, property *prn, specification *spec) ;
#line 610 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_substitution_test(OUTPUT_STREAM, specification *in, specification *spec) ;
#line 627 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_substitution_now(OUTPUT_STREAM, specification *in, specification *spec) ;
#line 647 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_extremal_of_S(OUTPUT_STREAM, specification *spec, property *prn, int sign) ;
#line 696 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_repeat_through_domain_S(OUTPUT_STREAM, specification *spec, local_variable *v1) ;
#line 777 "inform7/Chapter 14/Deciding to Defer.w"
void compile_repeat_call(OUTPUT_STREAM, specification *spec, local_variable *fromv) ;
#line 790 "inform7/Chapter 14/Deciding to Defer.w"
void compile_repeat_domain(OUTPUT_STREAM, pcalc_prop *prop, local_variable *fromv) ;
#line 802 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_loop_over_list_S(OUTPUT_STREAM, specification *spec, local_variable *v1) ;
#line 832 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__prop_verify_descriptive(pcalc_prop *prop, char *billing, specification *constructor) ;
#line 63 "inform7/Chapter 14/Cinders and Deferrals.w"
int Calculus__Deferrals__Cinders__find(OUTPUT_STREAM, pcalc_prop *prop, pcalc_prop_deferral *pdef) ;
#line 77 "inform7/Chapter 14/Cinders and Deferrals.w"
int cind_find_in_term(OUTPUT_STREAM, pcalc_term *pt, int cinder_number, int *started) ;
#line 115 "inform7/Chapter 14/Cinders and Deferrals.w"
int spec_needs_to_be_cindered(specification *spec) ;
#line 131 "inform7/Chapter 14/Cinders and Deferrals.w"
void Calculus__Deferrals__Cinders__declare(pcalc_prop *prop, pcalc_prop_deferral *pdef) ;
#line 145 "inform7/Chapter 14/Cinders and Deferrals.w"
int cind_declare_in(int cinder_number, pcalc_term *pt) ;
#line 163 "inform7/Chapter 14/Cinders and Deferrals.w"
kind * Calculus__Deferrals__Cinders__kind_of_value_of_term(pcalc_term pt) ;
#line 197 "inform7/Chapter 14/Cinders and Deferrals.w"
void Calculus__Terms__compile(OUTPUT_STREAM, pcalc_term pt) ;
#line 235 "inform7/Chapter 14/Cinders and Deferrals.w"
int Calculus__Deferrals__detect_locals(pcalc_prop *prop, specification **example) ;
#line 247 "inform7/Chapter 14/Cinders and Deferrals.w"
int detect_local_in_term(pcalc_term *pt, int locals_count, specification **example) ;
#line 255 "inform7/Chapter 14/Cinders and Deferrals.w"
int detect_local_in_spec(specification *spec, int locals_count, specification **example) ;
#line 16 "inform7/Chapter 14/Compile Deferred Propositions.w"
void compile_comment_about_deferral_reason(OUTPUT_STREAM, int reason) ;
#line 48 "inform7/Chapter 14/Compile Deferred Propositions.w"
void Calculus__Propositions__compile_remaining_deferred(OUTPUT_STREAM) ;
#line 53 "inform7/Chapter 14/Compile Deferred Propositions.w"
int Calculus__Propositions__compilation_coroutine(OUTPUT_STREAM) ;
#line 1216 "inform7/Chapter 14/Compile Deferred Propositions.w"
pcalc_prop * compile_loop_header(OUTPUT_STREAM, int var, pcalc_prop *proposition, int avoid_parent_optimisation, int grouped, pcalc_prop_deferral *pdef) ;
#line 283 "inform7/Chapter 15/Kinds.w"
kind * Kinds__base_construction(kind_constructor *con) ;
#line 313 "inform7/Chapter 15/Kinds.w"
kind * Kinds__intermediate_construction(unit_sequence *ik) ;
#line 331 "inform7/Chapter 15/Kinds.w"
kind * Kinds__variable_construction(int N, kind *declaration) ;
#line 352 "inform7/Chapter 15/Kinds.w"
kind * Kinds__unary_construction(kind_constructor *con, kind *X) ;
#line 361 "inform7/Chapter 15/Kinds.w"
kind * Kinds__binary_construction(kind_constructor *con, kind *X, kind *Y) ;
#line 409 "inform7/Chapter 15/Kinds.w"
kind * Kinds__function_kind(int no_args, kind **args, kind *return_K) ;
#line 422 "inform7/Chapter 15/Kinds.w"
kind * Kinds__pair_kind(kind *X, kind *Y) ;
#line 443 "inform7/Chapter 15/Kinds.w"
kind * first_base_k(void) ;
#line 451 "inform7/Chapter 15/Kinds.w"
kind * next_base_k(kind *K) ;
#line 465 "inform7/Chapter 15/Kinds.w"
kind_constructor * Kinds__get_construct(kind *K) ;
#line 473 "inform7/Chapter 15/Kinds.w"
int Kinds__is_intermediate(kind *K) ;
#line 478 "inform7/Chapter 15/Kinds.w"
int Kinds__get_variable_number(kind *K) ;
#line 483 "inform7/Chapter 15/Kinds.w"
kind * Kinds__get_variable_stipulation(kind *K) ;
#line 491 "inform7/Chapter 15/Kinds.w"
int Kinds__is_proper_constructor(kind *K) ;
#line 496 "inform7/Chapter 15/Kinds.w"
int Kinds__arity_of_constructor(kind *K) ;
#line 504 "inform7/Chapter 15/Kinds.w"
kind * Kinds__unary_construction_material(kind *K) ;
#line 512 "inform7/Chapter 15/Kinds.w"
void Kinds__binary_construction_material(kind *K, kind **X, kind **Y) ;
#line 526 "inform7/Chapter 15/Kinds.w"
int Kinds__contains(kind *K, kind_constructor *con) ;
#line 549 "inform7/Chapter 15/Kinds.w"
kind * Kinds__substitute(kind *K, kind **meanings, int *changed) ;
#line 585 "inform7/Chapter 15/Kinds.w"
kind * Kinds__weaken(kind *K) ;
#line 607 "inform7/Chapter 15/Kinds.w"
kind * Kinds__dereference_properties(kind *K) ;
#line 650 "inform7/Chapter 15/Kinds.w"
kind * Kinds__new_base(int w1, int w2, kind *super) ;
#line 724 "inform7/Chapter 15/Kinds.w"
kind_constructor ** Kinds__known_constructor_name(char *sn) ;
#line 742 "inform7/Chapter 15/Kinds.w"
kind ** Kinds__known_kind_name(char *sn) ;
#line 767 "inform7/Chapter 15/Kinds.w"
int Kinds__Constructors__known_name(char *sn) ;
#line 116 "inform7/Chapter 15/Kind Checking.w"
int Kinds__le(kind *from, kind *to) ;
#line 121 "inform7/Chapter 15/Kind Checking.w"
int Kinds__lt(kind *from, kind *to) ;
#line 145 "inform7/Chapter 15/Kind Checking.w"
int Kinds__eq(kind *K1, kind *K2) ;
#line 168 "inform7/Chapter 15/Kind Checking.w"
kind * Kinds__super(kind *K) ;
#line 182 "inform7/Chapter 15/Kind Checking.w"
kind * Kinds__max(kind *K1, kind *K2) ;
#line 194 "inform7/Chapter 15/Kind Checking.w"
kind * traverse_kind_poset(kind *K1, kind *K2, int direction) ;
#line 231 "inform7/Chapter 15/Kind Checking.w"
kind * Kinds__accumulative_max(kind *K1, kind *K2) ;
#line 259 "inform7/Chapter 15/Kind Checking.w"
int Kinds__compatible(kind *from, kind *to) ;
#line 278 "inform7/Chapter 15/Kind Checking.w"
int test_kind_relation(kind *from, kind *to, int comp) ;
#line 436 "inform7/Chapter 15/Kind Checking.w"
void Kinds__show_variables(void) ;
#line 450 "inform7/Chapter 15/Kind Checking.w"
int Kinds__Constructors__compatible(kind_constructor *from, kind_constructor *to, int allow_casts) ;
#line 461 "inform7/Chapter 15/Kind Checking.w"
void Kinds__make_subkind(kind *sub, kind *super) ;
#line 508 "inform7/Chapter 15/Kind Checking.w"
void Kinds__log_poset(int n) ;
#line 156 "inform7/Chapter 15/Kind Constructors.w"
kind_constructor * Kinds__Constructors__new(kind_constructor *super, char *source_name, char *initialisation_macro) ;
#line 305 "inform7/Chapter 15/Kind Constructors.w"
void Kinds__Constructors__attach_nametag(kind_constructor *con, nametag *nt) ;
#line 310 "inform7/Chapter 15/Kind Constructors.w"
void Kinds__Constructors__get_name(kind_constructor *con, int *w1, int *w2, int plural_form) ;
#line 318 "inform7/Chapter 15/Kind Constructors.w"
void Kinds__Constructors__get_name_in_play(kind_constructor *con, int *w1, int *w2, int plural_form) ;
#line 326 "inform7/Chapter 15/Kind Constructors.w"
nametag * Kinds__Constructors__get_nametag(kind_constructor *con) ;
#line 338 "inform7/Chapter 15/Kind Constructors.w"
void Kinds__Constructors__compile_I6_constants(OUTPUT_STREAM) ;
#line 349 "inform7/Chapter 15/Kind Constructors.w"
char * Kinds__Constructors__name_in_template_code(kind_constructor *con) ;
#line 358 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__convert_to_unit(kind_constructor *con) ;
#line 368 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__convert_to_enumeration(kind_constructor *con) ;
#line 384 "inform7/Chapter 15/Kind Constructors.w"
void Kinds__Constructors__convert_to_real(kind_constructor *con) ;
#line 393 "inform7/Chapter 15/Kind Constructors.w"
void Kinds__Constructors__mark_as_linguistic(kind_constructor *con) ;
#line 400 "inform7/Chapter 15/Kind Constructors.w"
kind ** Kinds__Constructors__cache_location(kind_constructor *con) ;
#line 405 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__arity(kind_constructor *con) ;
#line 411 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__tupling(kind_constructor *con, int b) ;
#line 415 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__variance(kind_constructor *con, int b) ;
#line 424 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__is_definite(kind_constructor *con) ;
#line 431 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__get_weak_ID(kind_constructor *con) ;
#line 436 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__is_arithmetic(kind_constructor *con) ;
#line 444 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__is_arithmetic_and_real(kind_constructor *con) ;
#line 452 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__is_enumeration(kind_constructor *con) ;
#line 465 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__find_cast(kind_constructor *from, kind_constructor *to) ;
#line 485 "inform7/Chapter 15/Kind Constructors.w"
int Kinds__Constructors__find_instance(kind_constructor *from, kind_constructor *to) ;
#line 504 "inform7/Chapter 15/Kind Constructors.w"
void Kinds__equate_latest(kind *K) ;
#line 250 "inform7/Chapter 15/Kind Interpreter.w"
void Kinds__Interpreter__start(void) ;
#line 269 "inform7/Chapter 15/Kind Interpreter.w"
void Kinds__Interpreter__despatch_kind_command(char *command) ;
#line 326 "inform7/Chapter 15/Kind Interpreter.w"
single_kind_command parse_kind_command(char *command) ;
#line 504 "inform7/Chapter 15/Kind Interpreter.w"
kind_template_definition * new_kind_template(char *name) ;
#line 510 "inform7/Chapter 15/Kind Interpreter.w"
kind_template_definition * parse_kind_template_name(char *name) ;
#line 524 "inform7/Chapter 15/Kind Interpreter.w"
int recording_a_kind_template(void) ;
#line 529 "inform7/Chapter 15/Kind Interpreter.w"
void begin_kind_template(char *name) ;
#line 537 "inform7/Chapter 15/Kind Interpreter.w"
void record_into_kind_template(char *line) ;
#line 541 "inform7/Chapter 15/Kind Interpreter.w"
void end_kind_template(void) ;
#line 553 "inform7/Chapter 15/Kind Interpreter.w"
void remember_to_transcribe_spec_template(kind_template_definition *ttd, kind_constructor *C) ;
#line 562 "inform7/Chapter 15/Kind Interpreter.w"
void Kinds__Interpreter__include_templates_for_kinds(void) ;
#line 568 "inform7/Chapter 15/Kind Interpreter.w"
void transcribe_kind_template(kind_template_definition *ttd, kind_constructor *con) ;
#line 658 "inform7/Chapter 15/Kind Interpreter.w"
void transcribe_constructor_name(char *buffer, kind_constructor *con, int lower_case) ;
#line 687 "inform7/Chapter 15/Kind Interpreter.w"
kind_macro_definition * new_kind_macro(char *name) ;
#line 694 "inform7/Chapter 15/Kind Interpreter.w"
kind_macro_definition * Kinds__Interpreter__parse_kind_macro_name(char *name) ;
#line 704 "inform7/Chapter 15/Kind Interpreter.w"
int recording_a_kind_macro(void) ;
#line 709 "inform7/Chapter 15/Kind Interpreter.w"
void begin_kind_macro(char *name) ;
#line 715 "inform7/Chapter 15/Kind Interpreter.w"
void record_into_kind_macro(single_kind_command stc) ;
#line 723 "inform7/Chapter 15/Kind Interpreter.w"
void end_kind_macro(void) ;
#line 732 "inform7/Chapter 15/Kind Interpreter.w"
void Kinds__Interpreter__play_back_kind_macro(kind_macro_definition *macro, kind_constructor *con) ;
#line 751 "inform7/Chapter 15/Kind Interpreter.w"
void initialise_kind_text_archiver(void) ;
#line 755 "inform7/Chapter 15/Kind Interpreter.w"
char * archive_kind_text(char *original) ;
#line 766 "inform7/Chapter 15/Kind Interpreter.w"
char * begin_recording_kind_text(void) ;
#line 772 "inform7/Chapter 15/Kind Interpreter.w"
void record_kind_text(char *line) ;
#line 777 "inform7/Chapter 15/Kind Interpreter.w"
void end_recording_kind_text(void) ;
#line 785 "inform7/Chapter 15/Kind Interpreter.w"
void kind_command_error(char *command, char *error) ;
#line 833 "inform7/Chapter 15/Kind Interpreter.w"
void apply_kind_command(single_kind_command stc, kind_constructor *con) ;
#line 1019 "inform7/Chapter 15/Kind Interpreter.w"
void Kinds__Interpreter__batch_done(void) ;
#line 11 "inform7/Chapter 15/Using Kinds.w"
void Kinds__get_name(kind *K, int *w1, int *w2, int plural_form) ;
#line 17 "inform7/Chapter 15/Using Kinds.w"
void Kinds__get_name_in_play(kind *K, int *w1, int *w2, int plural_form) ;
#line 23 "inform7/Chapter 15/Using Kinds.w"
nametag * Kinds__get_nametag(kind *K) ;
#line 33 "inform7/Chapter 15/Using Kinds.w"
int Kinds__is_kind_of_kind(kind *K) ;
#line 44 "inform7/Chapter 15/Using Kinds.w"
int Kinds__definite(kind *K) ;
#line 54 "inform7/Chapter 15/Using Kinds.w"
int Kinds__semidefinite(kind *K) ;
#line 65 "inform7/Chapter 15/Using Kinds.w"
int Kinds__involves_var(kind *K, int v) ;
#line 86 "inform7/Chapter 15/Using Kinds.w"
int Kinds__is_built_in(kind *K) ;
#line 92 "inform7/Chapter 15/Using Kinds.w"
parse_node * Kinds__get_creating_sentence(kind *K) ;
#line 105 "inform7/Chapter 15/Using Kinds.w"
int Kinds__is_uncertainly_defined(kind *K) ;
#line 113 "inform7/Chapter 15/Using Kinds.w"
int Kinds__is_an_enumeration(kind *K) ;
#line 123 "inform7/Chapter 15/Using Kinds.w"
int Kinds__convert_to_unit(kind *K) ;
#line 131 "inform7/Chapter 15/Using Kinds.w"
void Kinds__convert_to_enumeration(kind *K) ;
#line 138 "inform7/Chapter 15/Using Kinds.w"
void Kinds__convert_to_real(kind *K) ;
#line 147 "inform7/Chapter 15/Using Kinds.w"
int Kinds__new_enumerated_value(kind *K) ;
#line 156 "inform7/Chapter 15/Using Kinds.w"
kind * Kinds__stored_as(kind *K) ;
#line 167 "inform7/Chapter 15/Using Kinds.w"
void Kinds__set_superkind_set_at(kind *K, parse_node *S) ;
#line 172 "inform7/Chapter 15/Using Kinds.w"
parse_node * Kinds__get_superkind_set_at(kind *K) ;
#line 183 "inform7/Chapter 15/Using Kinds.w"
int Kinds__has_named_constant_values(kind *K) ;
#line 195 "inform7/Chapter 15/Using Kinds.w"
int Kinds__get_constant_compilation_method(kind *K) ;
#line 206 "inform7/Chapter 15/Using Kinds.w"
void Kinds__add_literal_pattern(kind *K, literal_pattern *lp) ;
#line 217 "inform7/Chapter 15/Using Kinds.w"
literal_pattern * Kinds__list_of_literal_forms(kind *K) ;
#line 225 "inform7/Chapter 15/Using Kinds.w"
int Kinds__get_highest_valid_value_as_integer(kind *K) ;
#line 244 "inform7/Chapter 15/Using Kinds.w"
int Kinds__has_properties(kind *K) ;
#line 265 "inform7/Chapter 15/Using Kinds.w"
inference_subject * Kinds__as_subject(kind *K) ;
#line 270 "inform7/Chapter 15/Using Kinds.w"
void Kinds__set_subject(kind *K, inference_subject *infs) ;
#line 279 "inform7/Chapter 15/Using Kinds.w"
void Kinds__Subjects__get_name_text(inference_subject *from, int *w1, int *w2) ;
#line 283 "inform7/Chapter 15/Using Kinds.w"
void Kinds__Subjects__complete_model(inference_subject *infs) ;
#line 284 "inform7/Chapter 15/Using Kinds.w"
void Kinds__Subjects__check_model(inference_subject *infs) ;
#line 286 "inform7/Chapter 15/Using Kinds.w"
void Kinds__Subjects__write_element_of_condition(inference_subject *infs, char *cond) ;
#line 298 "inform7/Chapter 15/Using Kinds.w"
general_pointer Kinds__Subjects__new_permission_granted(inference_subject *from) ;
#line 308 "inform7/Chapter 15/Using Kinds.w"
void Kinds__Subjects__make_adj_const_domain(inference_subject *infs, instance *nc, property *prn) ;
#line 318 "inform7/Chapter 15/Using Kinds.w"
void Kinds__Subjects__compile(OUTPUT_STREAM, inference_subject *infs) ;
#line 323 "inform7/Chapter 15/Using Kinds.w"
int Kinds__Subjects__compile_all(OUTPUT_STREAM) ;
#line 338 "inform7/Chapter 15/Using Kinds.w"
int Kinds__compile_default_value(OUTPUT_STREAM, kind *K, int w1, int w2, char *storage_name) ;
#line 466 "inform7/Chapter 15/Using Kinds.w"
char * get_default_value_of_kind(kind *K) ;
#line 507 "inform7/Chapter 15/Using Kinds.w"
int Kinds__name_can_coincide_with_property(kind *K) ;
#line 512 "inform7/Chapter 15/Using Kinds.w"
property * Kinds__get_coinciding_property(kind *K) ;
#line 517 "inform7/Chapter 15/Using Kinds.w"
void Kinds__set_coinciding_property(kind *K, property *P) ;
#line 528 "inform7/Chapter 15/Using Kinds.w"
int Kinds__uses_signed_comparisons(kind *K) ;
#line 534 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_comparison_routine(kind *K) ;
#line 547 "inform7/Chapter 15/Using Kinds.w"
int Kinds__is_quasinumerical(kind *K) ;
#line 552 "inform7/Chapter 15/Using Kinds.w"
unit_sequence * Kinds__get_dimensional_form(kind *K) ;
#line 559 "inform7/Chapter 15/Using Kinds.w"
int Kinds__test_if_derived(kind *K) ;
#line 564 "inform7/Chapter 15/Using Kinds.w"
void Kinds__now_derived(kind *K) ;
#line 569 "inform7/Chapter 15/Using Kinds.w"
int Kinds__scale_factor(kind *K) ;
#line 580 "inform7/Chapter 15/Using Kinds.w"
dimensional_rules * Kinds__get_dim_rules(kind *K) ;
#line 588 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_name_in_template_code(kind *K) ;
#line 597 "inform7/Chapter 15/Using Kinds.w"
kind_constructor * Kinds__Constructors__parse(char *sn) ;
#line 613 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__I6_classname(kind *K) ;
#line 620 "inform7/Chapter 15/Using Kinds.w"
int Kinds__I6_classnumber(kind *K) ;
#line 629 "inform7/Chapter 15/Using Kinds.w"
void Kinds__write_support_routine_name(OUTPUT_STREAM, kind *K) ;
#line 643 "inform7/Chapter 15/Using Kinds.w"
int Kinds__uses_pointer_values(kind *K) ;
#line 651 "inform7/Chapter 15/Using Kinds.w"
int Kinds__get_small_block_size(kind *K) ;
#line 660 "inform7/Chapter 15/Using Kinds.w"
int Kinds__get_heap_size_estimate(kind *K) ;
#line 665 "inform7/Chapter 15/Using Kinds.w"
int dt_uses_pointer_values(kind_constructor *con) ;
#line 672 "inform7/Chapter 15/Using Kinds.w"
int allow_word_as_pointer(kind_constructor *left, kind_constructor *right) ;
#line 684 "inform7/Chapter 15/Using Kinds.w"
int Kinds__allow_word_as_pointer(kind *left, kind *right) ;
#line 692 "inform7/Chapter 15/Using Kinds.w"
int Kinds__cast_possible(kind *from, kind *to) ;
#line 708 "inform7/Chapter 15/Using Kinds.w"
int Kinds__cast_call(OUTPUT_STREAM, kind *from, kind *to) ;
#line 727 "inform7/Chapter 15/Using Kinds.w"
specification * Kinds__cast_constant(specification *value, kind *to) ;
#line 763 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__interpret_test_equality(kind *left, kind *right) ;
#line 804 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__interpret_store(int storage_class, kind *left, kind *right, int inc) ;
#line 837 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_distinguisher(kind *K) ;
#line 848 "inform7/Chapter 15/Using Kinds.w"
int Kinds__compile_domain_possible(kind *K) ;
#line 878 "inform7/Chapter 15/Using Kinds.w"
int Kinds__write_loop_schema(i6_schema *sch, kind *K, int use_ix) ;
#line 933 "inform7/Chapter 15/Using Kinds.w"
int Kinds__requires_blanks_bitmap(kind *K) ;
#line 944 "inform7/Chapter 15/Using Kinds.w"
int Kinds__can_exchange(kind *K) ;
#line 954 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_name_of_printing_rule(kind *K) ;
#line 965 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_name_of_printing_rule_ACTIONS(kind *K) ;
#line 979 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_explicit_I6_GPR(kind *K) ;
#line 988 "inform7/Chapter 15/Using Kinds.w"
int Kinds__offers_I6_GPR(kind *K) ;
#line 997 "inform7/Chapter 15/Using Kinds.w"
int Kinds__request_I6_GPR(kind *K) ;
#line 1008 "inform7/Chapter 15/Using Kinds.w"
int Kinds__needs_I6_GPR(kind *K) ;
#line 1023 "inform7/Chapter 15/Using Kinds.w"
void Kinds__set_parsing_grammar(kind *K, grammar_verb *gv) ;
#line 1029 "inform7/Chapter 15/Using Kinds.w"
grammar_verb * Kinds__get_parsing_grammar(kind *K) ;
#line 1040 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_recognition_only_GPR(kind *K) ;
#line 1048 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_documentation_reference(kind *K) ;
#line 1053 "inform7/Chapter 15/Using Kinds.w"
void Kinds__set_documentation_reference(kind *K, char *dr) ;
#line 1062 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_index_default_value(kind *K) ;
#line 1067 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_index_minimum_value(kind *K) ;
#line 1072 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_index_maximum_value(kind *K) ;
#line 1081 "inform7/Chapter 15/Using Kinds.w"
char * get_kind_description(kind *K) ;
#line 1086 "inform7/Chapter 15/Using Kinds.w"
int Kinds__get_index_priority(kind *K) ;
#line 1091 "inform7/Chapter 15/Using Kinds.w"
int Kinds__indexed_grey_if_empty(kind *K) ;
#line 1102 "inform7/Chapter 15/Using Kinds.w"
void Kinds__set_specification_text(kind *K, char *desc) ;
#line 1107 "inform7/Chapter 15/Using Kinds.w"
char * Kinds__get_specification_text(kind *K) ;
#line 302 "inform7/Chapter 15/Describing Kinds.w"
int parse_constructor_name(kind_constructor *con, int *K1, int *K2, int *L1, int *L2) ;
#line 384 "inform7/Chapter 15/Describing Kinds.w"
int Parser__SP__parse_kind_variable_text(vocabulary_entry *ve) ;
#line 389 "inform7/Chapter 15/Describing Kinds.w"
int parse_kind_variable_name(char *p, int allow_lower) ;
#line 398 "inform7/Chapter 15/Describing Kinds.w"
int parse_kind_variable_name_singular(char *p) ;
#line 495 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__log(kind *K) ;
#line 502 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__Textual__write(OUTPUT_STREAM, kind *K) ;
#line 506 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__Textual__write_plural(OUTPUT_STREAM, kind *K) ;
#line 513 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__Textual__write_articled(OUTPUT_STREAM, kind *K) ;
#line 523 "inform7/Chapter 15/Describing Kinds.w"
void stream_kind_r(OUTPUT_STREAM, kind *K, int plural_form, int substituting) ;
#line 674 "inform7/Chapter 15/Describing Kinds.w"
void desc_base(OUTPUT_STREAM, kind_constructor *con, int b, kind *K, int substituting) ;
#line 722 "inform7/Chapter 15/Describing Kinds.w"
int Kinds__RuntimeIDs__weak(kind *K) ;
#line 731 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__RuntimeIDs__compile_weak(OUTPUT_STREAM, kind *K) ;
#line 779 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__RuntimeIDs__compile_strong(OUTPUT_STREAM, kind *K) ;
#line 800 "inform7/Chapter 15/Describing Kinds.w"
runtime_kind_structure * get_rks(kind *K) ;
#line 872 "inform7/Chapter 15/Describing Kinds.w"
int Kinds__RuntimeIDs__compile_default_value(OUTPUT_STREAM, kind *K) ;
#line 880 "inform7/Chapter 15/Describing Kinds.w"
int Kinds__RuntimeIDs__precompile_default_value(kind *K) ;
#line 900 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__compile_runtime_id_structures(OUTPUT_STREAM) ;
#line 326 "inform7/Chapter 15/Dimensions.w"
int kind_prior(kind *A, kind *B) ;
#line 343 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__dim_initialise(dimensional_rules *dimrs) ;
#line 350 "inform7/Chapter 15/Dimensions.w"
void record_multiplication_rule(kind *left, kind *right, kind *outcome) ;
#line 396 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__dim_set_multiplication(kind *left, kind *right, kind *outcome) ;
#line 431 "inform7/Chapter 15/Dimensions.w"
int Kinds__Dimensions__arithmetic_op_is_unary(int op) ;
#line 458 "inform7/Chapter 15/Dimensions.w"
int Kinds__Dimensions__gcd(int m, int n) ;
#line 471 "inform7/Chapter 15/Dimensions.w"
int lcm(int m, int n) ;
#line 481 "inform7/Chapter 15/Dimensions.w"
unit_sequence Kinds__Dimensions__fundamental_unit_sequence(kind *B) ;
#line 497 "inform7/Chapter 15/Dimensions.w"
int Kinds__Dimensions__compare_unit_sequences(unit_sequence *ik1, unit_sequence *ik2) ;
#line 533 "inform7/Chapter 15/Dimensions.w"
void multiply_unit_sequences(unit_sequence *us1, int s1, unit_sequence *us2, int s2, unit_sequence *result) ;
#line 633 "inform7/Chapter 15/Dimensions.w"
int root_unit_sequence(unit_sequence *us, int pow, unit_sequence *result) ;
#line 653 "inform7/Chapter 15/Dimensions.w"
void dim_substitute(unit_sequence *existing, kind *fundamental, unit_sequence *derived) ;
#line 684 "inform7/Chapter 15/Dimensions.w"
int Kinds__Dimensions__us_get_scaling_factor(unit_sequence *us) ;
#line 692 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__index_unit_sequence(OUTPUT_STREAM, unit_sequence *deriv, int briefly) ;
#line 725 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__log_unit_sequence(unit_sequence *deriv) ;
#line 755 "inform7/Chapter 15/Dimensions.w"
void make_unit_derivation(kind *left, kind *right, kind *outcome) ;
#line 842 "inform7/Chapter 15/Dimensions.w"
int Kinds__Dimensions__dimensionless(kind *K) ;
#line 856 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__index_dimensional_rules(void) ;
#line 979 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__log_unit_analysis(void) ;
#line 999 "inform7/Chapter 15/Dimensions.w"
int kind_is_derived(kind *K) ;
#line 1040 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__kind_rescale_multiplication(OUTPUT_STREAM, kind *kindx, kind *kindy) ;
#line 1057 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__kind_rescale_division(OUTPUT_STREAM, kind *kindx, kind *kindy) ;
#line 1071 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__kind_rescale_root(OUTPUT_STREAM, kind *kindx, int power) ;
#line 1120 "inform7/Chapter 15/Dimensions.w"
kind * Kinds__Dimensions__arithmetic_on_kinds(kind *K1, kind *K2, int op) ;
#line 1228 "inform7/Chapter 15/Dimensions.w"
void Kinds__perform_arithmetic(OUTPUT_STREAM, int op, equation *eqn, specification *X, equation_node *EX, kind *KX, specification *Y, equation_node *EY, kind *KY) ;
#line 1525 "inform7/Chapter 15/Dimensions.w"
void begin_flotation(OUTPUT_STREAM, kind *K) ;
#line 1531 "inform7/Chapter 15/Dimensions.w"
void end_flotation(OUTPUT_STREAM, kind *K) ;
#line 1538 "inform7/Chapter 15/Dimensions.w"
void begin_deflotation(OUTPUT_STREAM, kind *K) ;
#line 1543 "inform7/Chapter 15/Dimensions.w"
void end_deflotation(OUTPUT_STREAM, kind *K) ;
#line 1553 "inform7/Chapter 15/Dimensions.w"
generalised_kind Kinds__Generalised__new(kind *K) ;
#line 1561 "inform7/Chapter 15/Dimensions.w"
kind * Kinds__Generalised__underlying(generalised_kind gK) ;
#line 1565 "inform7/Chapter 15/Dimensions.w"
int Kinds__Generalised__uses_floating_point(generalised_kind gK) ;
#line 1571 "inform7/Chapter 15/Dimensions.w"
generalised_kind Kinds__Generalised__to_integer(generalised_kind gK) ;
#line 1585 "inform7/Chapter 15/Dimensions.w"
generalised_kind Kinds__Generalised__to_real(generalised_kind gK) ;
#line 1599 "inform7/Chapter 15/Dimensions.w"
int Kinds__uses_floating_point(kind *K) ;
#line 1604 "inform7/Chapter 15/Dimensions.w"
kind * Kinds__to_real(kind *K) ;
#line 1609 "inform7/Chapter 15/Dimensions.w"
kind * Kinds__to_integer(kind *K) ;
#line 81 "inform7/Chapter 15/Scaled Arithmetic Values.w"
void Kinds__Scalings__describe(OUTPUT_STREAM, scaling_transformation sc) ;
#line 102 "inform7/Chapter 15/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 15/Scaled Arithmetic Values.w"
void Kinds__Scalings__convert_to_real(scaling_transformation *sc) ;
#line 136 "inform7/Chapter 15/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 15/Scaled Arithmetic Values.w"
scaling_transformation Kinds__Scalings__enlarge(scaling_transformation sc, int F) ;
#line 271 "inform7/Chapter 15/Scaled Arithmetic Values.w"
scaling_transformation Kinds__Scalings__contract(scaling_transformation sc, int F, int *loses_accuracy) ;
#line 288 "inform7/Chapter 15/Scaled Arithmetic Values.w"
int Kinds__Scalings__compare(scaling_transformation A, scaling_transformation B) ;
#line 309 "inform7/Chapter 15/Scaled Arithmetic Values.w"
int Kinds__Scalings__get_integer_multiplier(scaling_transformation sc) ;
#line 316 "inform7/Chapter 15/Scaled Arithmetic Values.w"
int Kinds__Scalings__involves_scale_change(scaling_transformation sc) ;
#line 328 "inform7/Chapter 15/Scaled Arithmetic Values.w"
int Kinds__Scalings__quantum(scaling_transformation sc) ;
#line 332 "inform7/Chapter 15/Scaled Arithmetic Values.w"
double Kinds__Scalings__real_quantum(scaling_transformation sc) ;
#line 340 "inform7/Chapter 15/Scaled Arithmetic Values.w"
int Kinds__Scalings__quanta_to_value(scaling_transformation sc, int q) ;
#line 344 "inform7/Chapter 15/Scaled Arithmetic Values.w"
double Kinds__Scalings__real_quanta_to_value(scaling_transformation sc, double q) ;
#line 360 "inform7/Chapter 15/Scaled Arithmetic Values.w"
void Kinds__Scalings__value_to_quanta(int v, scaling_transformation sc, int *q, int *r) ;
#line 366 "inform7/Chapter 15/Scaled Arithmetic Values.w"
double Kinds__Scalings__real_value_to_quanta(double v, scaling_transformation sc) ;
#line 376 "inform7/Chapter 15/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 15/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 15/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 15/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_threshold_test(OUTPUT_STREAM, scaling_transformation sc, char *V_var, char *op) ;
#line 484 "inform7/Chapter 15/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 15/Scaled Arithmetic Values.w"
void Kinds__Scalings__I6_real_literal(OUTPUT_STREAM, double x) ;
#line 26 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__ensure_basic_heap_present(void) ;
#line 35 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_heap_allocator(OUTPUT_STREAM) ;
#line 68 "inform7/Chapter 15/Runtime Support for Kinds.w"
STREAM * Kinds__RunTime__begin_block_constant(OUTPUT_STREAM, kind *K) ;
#line 81 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__end_block_constant(kind *K) ;
#line 88 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_block_constants(OUTPUT_STREAM) ;
#line 105 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_heap_allocation(OUTPUT_STREAM, kind *K, int multiplier, int stack_offset) ;
#line 131 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_block_value_header(OUTPUT_STREAM, kind *K, int individual, int size) ;
#line 154 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_data_type_support_routines(OUTPUT_STREAM) ;
#line 439 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__I7_Kind_Name_routine(OUTPUT_STREAM) ;
#line 459 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__notify_of_use(kind *K) ;
#line 25 "inform7/Chapter 15/Kinds Index.w"
void Kinds__Index__index_kinds(int pass) ;
#line 253 "inform7/Chapter 15/Kinds Index.w"
void index_kind_col_head(char *name, char *anchor) ;
#line 266 "inform7/Chapter 15/Kinds Index.w"
void Kinds__Index__begin_chart_row(void) ;
#line 285 "inform7/Chapter 15/Kinds Index.w"
int index_kind_name_cell(int shaded, kind *K) ;
#line 303 "inform7/Chapter 15/Kinds Index.w"
void Kinds__Index__end_chart_row(int shaded, kind *K, char *tick1, char *tick2, char *tick3) ;
#line 360 "inform7/Chapter 15/Kinds Index.w"
void Kinds__Index__index_kind(kind *K, int plural, int with_links) ;
#line 181 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__make_type_IDs_table(void) ;
#line 213 "inform7/Chapter 16/Taxonomy of Specifications.w"
taxa_observations * type_ID_pair_rules(int r, int s) ;
#line 224 "inform7/Chapter 16/Taxonomy of Specifications.w"
void type_ID_enlarge_types_table(int to_size) ;
#line 291 "inform7/Chapter 16/Taxonomy of Specifications.w"
void type_ID_details_initialise(taxon *tidr, int i) ;
#line 298 "inform7/Chapter 16/Taxonomy of Specifications.w"
void tpr_initialise(taxa_observations *tpr) ;
#line 310 "inform7/Chapter 16/Taxonomy of Specifications.w"
int Specifications__Taxa__exists(int t) ;
#line 320 "inform7/Chapter 16/Taxonomy of Specifications.w"
int Specifications__Taxa__is_family_ID(int t) ;
#line 330 "inform7/Chapter 16/Taxonomy of Specifications.w"
int Specifications__Taxa__get_family_of_species(int t) ;
#line 338 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__set_flag(int t, int f) ;
#line 343 "inform7/Chapter 16/Taxonomy of Specifications.w"
int Specifications__Taxa__test_flag(int t, int f) ;
#line 362 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__log(int id) ;
#line 371 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__set_source_name(int id, char *d) ;
#line 378 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__set_parsing_names(int t, vocabulary_entry *singular, vocabulary_entry *plural) ;
#line 401 "inform7/Chapter 16/Taxonomy of Specifications.w"
char * name_of_spec_context(int context) ;
#line 412 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__permit_pair(int a, int b, int map) ;
#line 425 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__observe(specification *spec, int context) ;
#line 469 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__report_pairs_observed(void) ;
#line 489 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__report_pairs_allowed(void) ;
#line 111 "inform7/Chapter 16/Specifications.w"
specification * Specifications__new(int family, int species) ;
#line 129 "inform7/Chapter 16/Specifications.w"
specification * Specifications__copy(specification *spec) ;
#line 144 "inform7/Chapter 16/Specifications.w"
void Specifications__coerce_to(specification *spec, int new_family, int new_species) ;
#line 154 "inform7/Chapter 16/Specifications.w"
int Specifications__species_is(specification *spec, int species) ;
#line 159 "inform7/Chapter 16/Specifications.w"
int Specifications__family_is(specification *spec, int family) ;
#line 167 "inform7/Chapter 16/Specifications.w"
int Specifications__get_species(specification *spec) ;
#line 172 "inform7/Chapter 16/Specifications.w"
int Specifications__get_family(specification *spec) ;
#line 181 "inform7/Chapter 16/Specifications.w"
int spec_test_ability(specification *spec, int f) ;
#line 193 "inform7/Chapter 16/Specifications.w"
int Specifications__is_UNKNOWN(specification *spec) ;
#line 198 "inform7/Chapter 16/Specifications.w"
specification * Specifications__Unknown__new(int w1, int w2) ;
#line 204 "inform7/Chapter 16/Specifications.w"
void Specifications__Unknown__coerce(specification *spec) ;
#line 216 "inform7/Chapter 16/Specifications.w"
void Specifications__make_actual(specification *spec) ;
#line 219 "inform7/Chapter 16/Specifications.w"
void Specifications__make_generic(specification *spec) ;
#line 226 "inform7/Chapter 16/Specifications.w"
int Specifications__is_actual(specification *spec) ;
#line 229 "inform7/Chapter 16/Specifications.w"
int Specifications__is_generic(specification *spec) ;
#line 238 "inform7/Chapter 16/Specifications.w"
void Specifications__set_flag(specification *spec, int flag) ;
#line 243 "inform7/Chapter 16/Specifications.w"
void Specifications__clear_flag(specification *spec, int flag) ;
#line 248 "inform7/Chapter 16/Specifications.w"
int Specifications__test_flag(specification *spec, int flag) ;
#line 257 "inform7/Chapter 16/Specifications.w"
void Specifications__set_data(specification *spec, int purpose, int data) ;
#line 266 "inform7/Chapter 16/Specifications.w"
int Specifications__get_data(specification *spec, int purpose) ;
#line 281 "inform7/Chapter 16/Specifications.w"
int Specifications__get_argc(specification *spec) ;
#line 286 "inform7/Chapter 16/Specifications.w"
specification * Specifications__get_argument(specification *spec, int c) ;
#line 295 "inform7/Chapter 16/Specifications.w"
void Specifications__set_argument(specification *spec, int c, specification *arg) ;
#line 310 "inform7/Chapter 16/Specifications.w"
kind * Specifications__get_kind(specification *spec) ;
#line 315 "inform7/Chapter 16/Specifications.w"
void Specifications__set_kind_of_value(specification *spec, kind *K) ;
#line 323 "inform7/Chapter 16/Specifications.w"
general_pointer Specifications__get_structure_field(specification *spec) ;
#line 328 "inform7/Chapter 16/Specifications.w"
void Specifications__set_structure_field(specification *spec, general_pointer gp) ;
#line 337 "inform7/Chapter 16/Specifications.w"
void Specifications__create_invocation_list(specification *spec) ;
#line 344 "inform7/Chapter 16/Specifications.w"
void Specifications__set_invocation_list(specification *spec, invocation_list *invl) ;
#line 351 "inform7/Chapter 16/Specifications.w"
invocation_list * Specifications__invocation_list(specification *spec) ;
#line 357 "inform7/Chapter 16/Specifications.w"
int Specifications__has_invocation_list(specification *spec) ;
#line 366 "inform7/Chapter 16/Specifications.w"
pcalc_prop * Specifications__get_proposition(specification *spec) ;
#line 371 "inform7/Chapter 16/Specifications.w"
void Specifications__set_proposition(specification *spec, pcalc_prop *prop) ;
#line 379 "inform7/Chapter 16/Specifications.w"
description_docket * Specifications__get_docket(specification *spec) ;
#line 384 "inform7/Chapter 16/Specifications.w"
void Specifications__set_docket(specification *spec, description_docket *dd) ;
#line 392 "inform7/Chapter 16/Specifications.w"
kind * Specifications__get_kind_referred_to(specification *spec) ;
#line 412 "inform7/Chapter 16/Specifications.w"
time_period * Specifications__get_condition_tense(specification *spec) ;
#line 417 "inform7/Chapter 16/Specifications.w"
void Specifications__set_condition_tense(specification *spec, time_period *tp) ;
#line 427 "inform7/Chapter 16/Specifications.w"
int Specifications__is_evaluating(specification *spec) ;
#line 431 "inform7/Chapter 16/Specifications.w"
kind * Specifications__evaluates_to(specification *spec) ;
#line 447 "inform7/Chapter 16/Specifications.w"
int Specifications__is_phrasal(specification *spec) ;
#line 457 "inform7/Chapter 16/Specifications.w"
void Specifications__write_out_in_English(OUTPUT_STREAM, specification *spec) ;
#line 476 "inform7/Chapter 16/Specifications.w"
void Specifications__log_concisely(specification *spec) ;
#line 480 "inform7/Chapter 16/Specifications.w"
void Specifications__log_exhaustively(specification *spec) ;
#line 488 "inform7/Chapter 16/Specifications.w"
void log_specification_recursively(specification *spec, int details) ;
#line 546 "inform7/Chapter 16/Specifications.w"
int Specifications__compare_specificity(specification *spec1, specification *spec2, int *wont_mix) ;
#line 135 "inform7/Chapter 16/Text to Specifications.w"
void Specifications__warn_expression_cache(void) ;
#line 147 "inform7/Chapter 16/Text to Specifications.w"
specification * parse_with_cache(int w1, int w2, int context) ;
#line 27 "inform7/Chapter 16/Specification Versions of Other Structures.w"
specification * Specifications__new_generic_from_type_ID(int ID_number) ;
#line 62 "inform7/Chapter 16/Specification Versions of Other Structures.w"
specification * Specifications__kind_as_spec(kind *K) ;
#line 76 "inform7/Chapter 16/Specification Versions of Other Structures.w"
int Specifications__describes_an_object_vaguely_or_exactly(specification *spec) ;
#line 83 "inform7/Chapter 16/Specification Versions of Other Structures.w"
instance * Specifications__object_exactly_described_if_any(specification *spec) ;
#line 85 "inform7/Chapter 16/Compiling from Specifications.w"
void Specifications__compile(OUTPUT_STREAM, specification *spec) ;
#line 99 "inform7/Chapter 16/Compiling from Specifications.w"
void spec_compile_primitive(OUTPUT_STREAM, specification *spec) ;
#line 130 "inform7/Chapter 16/Compiling from Specifications.w"
void Specifications__compile_to_kind(OUTPUT_STREAM, specification *value, kind *K_wanted) ;
#line 151 "inform7/Chapter 16/Compiling from Specifications.w"
void Specifications__compile_constant_to_kind(OUTPUT_STREAM, specification *value, kind *K_wanted) ;
#line 22 "inform7/Chapter 16/MATCHING Specifications.w"
void Specifications__Matching__create_species(void) ;
#line 31 "inform7/Chapter 16/MATCHING Specifications.w"
specification * Specifications__Matching__new_NEW_LOCAL_VARIABLE_NAME(kind *K) ;
#line 42 "inform7/Chapter 16/MATCHING Specifications.w"
void Specifications__Matching__write_out_in_English(OUTPUT_STREAM, specification *spec) ;
#line 46 "inform7/Chapter 16/MATCHING Specifications.w"
void Specifications__Matching__log(specification *spec) ;
#line 54 "inform7/Chapter 16/MATCHING Specifications.w"
kind * Specifications__Matching__kind_when_evaluated(specification *spec) ;
#line 58 "inform7/Chapter 16/MATCHING Specifications.w"
void Specifications__Matching__compile(OUTPUT_STREAM, specification *spec_found) ;
#line 48 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__create_species(void) ;
#line 76 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__new_actual_CONSTANT(kind *K) ;
#line 82 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__new_generic_CONSTANT(kind *K) ;
#line 99 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__new_self_object_constant(void) ;
#line 105 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__new_nothing_object_constant(void) ;
#line 115 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__new_named_CONSTANT(instance *nc) ;
#line 119 "inform7/Chapter 16/VALUE Specifications.w"
instance * Specifications__Values__get_named_constant_if_any(specification *spec) ;
#line 132 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__new_PHRASE_TO_DECIDE_VALUE(void) ;
#line 147 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__coerce_DESCRIPTION_to_VALUE(specification *spec, kind *K) ;
#line 169 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__coerce_UNDERSTANDING_to_TEXT(specification *spec) ;
#line 178 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__coerce_NUMBER_to_REAL_NUMBER(specification *spec) ;
#line 189 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_actual_CONSTANT(specification *spec) ;
#line 194 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_generic_CONSTANT(specification *spec) ;
#line 202 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_CONSTANT_object(specification *spec) ;
#line 209 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_CONSTANT_construction(specification *spec, kind_constructor *con) ;
#line 216 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_CONSTANT_of_kind(specification *spec, kind *K) ;
#line 223 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_actual_CONSTANT_object(specification *spec) ;
#line 231 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_actual_CONSTANT_construction(specification *spec, kind_constructor *con) ;
#line 238 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_actual_CONSTANT_of_kind(specification *spec, kind *K) ;
#line 244 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_generic_CONSTANT_of_kind(specification *spec, kind *K) ;
#line 250 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_generic_CONSTANT_construction(specification *spec, kind_constructor *con) ;
#line 261 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_nothing_object_constant(specification *spec) ;
#line 266 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_self_object_constant(specification *spec) ;
#line 271 "inform7/Chapter 16/VALUE Specifications.w"
instance * Specifications__Values__instance_of_CONSTANT_object_if_any(specification *spec) ;
#line 284 "inform7/Chapter 16/VALUE Specifications.w"
property * Specifications__Values__get_property_name_if_any(specification *spec) ;
#line 295 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__new_integer_literal(int n) ;
#line 309 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__get_literal_value(specification *spec) ;
#line 332 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__new_text_literal(char *x) ;
#line 341 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__new_text_literal_from_stream(STREAM *S) ;
#line 347 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__faux_text_literal_from_stream(STREAM *S) ;
#line 357 "inform7/Chapter 16/VALUE Specifications.w"
specification * Specifications__Values__new_pair_combination(specification *X, specification *Y) ;
#line 371 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__extract_pair(specification *pair, specification **X, specification **Y) ;
#line 410 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__compare_CONSTANT(specification *spec1, specification *spec2) ;
#line 467 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__write_out_in_English(OUTPUT_STREAM, specification *spec) ;
#line 495 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__log(specification *spec) ;
#line 516 "inform7/Chapter 16/VALUE Specifications.w"
kind * Specifications__Values__kind_when_VALUE_is_evaluated(specification *spec) ;
#line 616 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__compile(OUTPUT_STREAM, specification *spec_found) ;
#line 82 "inform7/Chapter 16/STORAGE Specifications.w"
void Specifications__Storage__create_species(void) ;
#line 137 "inform7/Chapter 16/STORAGE Specifications.w"
specification * Specifications__Storage__new_LOCAL_VARIABLE(int w1, int w2, local_variable *lvar) ;
#line 145 "inform7/Chapter 16/STORAGE Specifications.w"
specification * Specifications__Storage__new_generic_LOCAL_VARIABLE(kind *K) ;
#line 153 "inform7/Chapter 16/STORAGE Specifications.w"
specification * Specifications__Storage__new_actual_NONLOCAL_VARIABLE(nonlocal_variable *nlv) ;
#line 161 "inform7/Chapter 16/STORAGE Specifications.w"
specification * Specifications__Storage__new_generic_NONLOCAL_VARIABLE(kind *K) ;
#line 172 "inform7/Chapter 16/STORAGE Specifications.w"
specification * Specifications__Storage__new_TABLE_ENTRY(void) ;
#line 180 "inform7/Chapter 16/STORAGE Specifications.w"
specification * Specifications__Storage__new_LIST_ENTRY(specification *owner, specification *index) ;
#line 196 "inform7/Chapter 16/STORAGE Specifications.w"
specification * Specifications__Storage__new_PROPERTY_VALUE(specification *prop, specification *owner) ;
#line 216 "inform7/Chapter 16/STORAGE Specifications.w"
specification * Specifications__Storage__underlying_property(specification *spec) ;
#line 228 "inform7/Chapter 16/STORAGE Specifications.w"
int Specifications__Storage__get_storage_form(specification *spec) ;
#line 233 "inform7/Chapter 16/STORAGE Specifications.w"
int Specifications__Storage__is_generic(specification *spec) ;
#line 242 "inform7/Chapter 16/STORAGE Specifications.w"
int Specifications__Storage__is_actual_NONLOCAL_VARIABLE(specification *spec) ;
#line 247 "inform7/Chapter 16/STORAGE Specifications.w"
nonlocal_variable * Specifications__Storage__get_nonlocal_variable_if_any(specification *spec) ;
#line 253 "inform7/Chapter 16/STORAGE Specifications.w"
int Specifications__Storage__is_constant_NONLOCAL_VARIABLE(specification *spec) ;
#line 259 "inform7/Chapter 16/STORAGE Specifications.w"
int Specifications__Storage__is_generic_NONLOCAL_VARIABLE(specification *spec) ;
#line 268 "inform7/Chapter 16/STORAGE Specifications.w"
int Specifications__Storage__is_global_variable(specification *spec) ;
#line 276 "inform7/Chapter 16/STORAGE Specifications.w"
void Specifications__Storage__write_out_in_English(OUTPUT_STREAM, specification *spec) ;
#line 303 "inform7/Chapter 16/STORAGE Specifications.w"
void Specifications__Storage__log(specification *spec) ;
#line 325 "inform7/Chapter 16/STORAGE Specifications.w"
kind * Specifications__Storage__kind_when_STORAGE_is_evaluated(specification *spec) ;
#line 385 "inform7/Chapter 16/STORAGE Specifications.w"
local_variable * Specifications__Storage__get_local_variable_if_any(specification *spec) ;
#line 396 "inform7/Chapter 16/STORAGE Specifications.w"
void Specifications__Storage__compile(OUTPUT_STREAM, specification *spec_found) ;
#line 568 "inform7/Chapter 16/STORAGE Specifications.w"
char * Specifications__Storage__storage_class_schema(int storage_class, int kind_of_store, int reducing_modulo_1440) ;
#line 167 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__create_species(void) ;
#line 229 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new(time_period *tp) ;
#line 238 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new_generic_CONDITION(void) ;
#line 247 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new_LOGICAL_AND(specification *spec1, specification *spec2) ;
#line 254 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new_LOGICAL_OR(specification *spec1, specification *spec2) ;
#line 265 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new_TEST_PROPOSITION(pcalc_prop *prop) ;
#line 275 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new_TEST_PHRASE_OPTION(int opt_num) ;
#line 284 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new_TEST_ACTION(action_pattern *ap) ;
#line 290 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new_TEST_PAST_ACTION(action_pattern *ap) ;
#line 300 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new_PHRASE_TO_DECIDE_IF(void) ;
#line 317 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new_DESCRIPTION(void) ;
#line 322 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__new_DESCRIPTION_of(kind *K) ;
#line 333 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__attach_tense(specification *spec, int t) ;
#line 346 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__coerce_TEST_PROPOSITION_to_NOW_PROPOSITION(specification *spec) ;
#line 360 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__coerce_generic_CONSTANT_to_DESCRIPTION(specification *spec) ;
#line 380 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__is_qualified_DESCRIPTION(specification *spec) ;
#line 388 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__is_complex_DESCRIPTION(specification *spec) ;
#line 395 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__is_adjectives_plus_kind_of_object_DESCRIPTION(specification *spec) ;
#line 411 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__restrict_DESCRIPTION_domain(specification *spec, instance *new_instance) ;
#line 433 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__restrict_DESCRIPTION_to_kind(specification *spec, kind *NK) ;
#line 442 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__write_out_in_English(OUTPUT_STREAM, specification *spec) ;
#line 465 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__log(specification *spec) ;
#line 489 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__compare_specificity_of_DESCRIPTIONs(specification *spec1, specification *spec2) ;
#line 563 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__compare_specificity_of_CONDITIONs(specification *spec1, specification *spec2) ;
#line 578 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__count(specification *spec) ;
#line 602 "inform7/Chapter 16/CONDITION Specifications.w"
kind * Specifications__Conditions__kind_when_CONDITION_is_evaluated(specification *spec) ;
#line 612 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__compile(OUTPUT_STREAM, specification *spec_found) ;
#line 699 "inform7/Chapter 16/CONDITION Specifications.w"
void spec_clear_docket(specification *spec) ;
#line 708 "inform7/Chapter 16/CONDITION Specifications.w"
description_docket * spec_find_docket(specification *spec, int create_if_necessary) ;
#line 731 "inform7/Chapter 16/CONDITION Specifications.w"
specification * Specifications__Conditions__copy_and_copy_docket(specification *spec) ;
#line 747 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__convert_docket_to_proposition(specification *spec) ;
#line 757 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__number_of_adjectives_applied_to(specification *spec) ;
#line 763 "inform7/Chapter 16/CONDITION Specifications.w"
int number_of_positive_adjectives_applied_to(specification *spec) ;
#line 769 "inform7/Chapter 16/CONDITION Specifications.w"
adjective_list_entry * Specifications__Conditions__first_adjective_list_entry(specification *spec) ;
#line 776 "inform7/Chapter 16/CONDITION Specifications.w"
void empty_adjective_list(specification *spec) ;
#line 784 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__add_to_adjective_list(adjective_list_entry *ale, specification *spec) ;
#line 794 "inform7/Chapter 16/CONDITION Specifications.w"
int types_have_same_adjective_list(specification *spec1, specification *spec2) ;
#line 805 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__attach_quantifier(specification *spec, quantifier *q, int par) ;
#line 811 "inform7/Chapter 16/CONDITION Specifications.w"
quantifier * Specifications__Conditions__get_quantifier(specification *spec) ;
#line 817 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__get_quantification_parameter(specification *spec) ;
#line 826 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__attach_calling(specification *spec, int c1, int c2) ;
#line 832 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__get_calling(specification *spec, int *c1, int *c2) ;
#line 838 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__clear_calling(specification *spec) ;
#line 843 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__makes_callings(specification *spec) ;
#line 854 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__set_described_kind(specification *spec, kind *K) ;
#line 859 "inform7/Chapter 16/CONDITION Specifications.w"
kind * Specifications__Conditions__get_described_kind(specification *spec) ;
#line 865 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__set_composite_flag(specification *spec) ;
#line 869 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__get_composite_flag(specification *spec) ;
#line 876 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__set_described_instance(specification *spec, instance *I) ;
#line 881 "inform7/Chapter 16/CONDITION Specifications.w"
instance * Specifications__Conditions__get_described_instance(specification *spec) ;
#line 896 "inform7/Chapter 16/CONDITION Specifications.w"
adjective_list_entry * Specifications__Conditions__new_adjective_list_entry(adjectival_phrase *aph, int pos) ;
#line 904 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__log_adjective_list_entry(adjective_list_entry *ale) ;
#line 912 "inform7/Chapter 16/CONDITION Specifications.w"
adjective_list_entry * Specifications__Conditions__copy_adjective_list_entry(adjective_list_entry *ale_from) ;
#line 916 "inform7/Chapter 16/CONDITION Specifications.w"
adjectival_phrase * Specifications__Conditions__get_adjective_from_list_entry(adjective_list_entry *ale) ;
#line 921 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__adjective_used_positively(adjective_list_entry *ale) ;
#line 77 "inform7/Chapter 16/COMMAND Specifications.w"
void Specifications__Commands__create_species(void) ;
#line 128 "inform7/Chapter 16/COMMAND Specifications.w"
specification * Specifications__Commands__new(void) ;
#line 133 "inform7/Chapter 16/COMMAND Specifications.w"
specification * Specifications__Commands__new_TO_PHRASE(void) ;
#line 139 "inform7/Chapter 16/COMMAND Specifications.w"
specification * Specifications__Commands__new_OTHERWISE(void) ;
#line 144 "inform7/Chapter 16/COMMAND Specifications.w"
specification * Specifications__Commands__new_CASE(specification *case_val) ;
#line 150 "inform7/Chapter 16/COMMAND Specifications.w"
specification * Specifications__Commands__new_default_CASE(void) ;
#line 155 "inform7/Chapter 16/COMMAND Specifications.w"
specification * Specifications__Commands__new_RULEBOOK_OUTCOME_COMMAND(named_rulebook_outcome *nro) ;
#line 161 "inform7/Chapter 16/COMMAND Specifications.w"
specification * Specifications__Commands__new_END_BLOCK(phrase *ph) ;
#line 172 "inform7/Chapter 16/COMMAND Specifications.w"
void Specifications__Commands__coerce_TEST_ACTION_to_TRY_ACTION(specification *spec, specification *nspec, specification *sspec, specification *aspec, int other_flag, action_name_list *anl) ;
#line 189 "inform7/Chapter 16/COMMAND Specifications.w"
void Specifications__Commands__write_out_in_English(OUTPUT_STREAM, specification *spec) ;
#line 193 "inform7/Chapter 16/COMMAND Specifications.w"
void Specifications__Commands__log(specification *spec) ;
#line 201 "inform7/Chapter 16/COMMAND Specifications.w"
kind * Specifications__Commands__kind_when_COMMAND_is_evaluated(specification *spec) ;
#line 210 "inform7/Chapter 16/COMMAND Specifications.w"
void Specifications__Commands__compile(OUTPUT_STREAM, specification *spec_found) ;
#line 357 "inform7/Chapter 16/COMMAND Specifications.w"
void compile_try_action_parameter(OUTPUT_STREAM, specification *spec, kind *required_kind) ;
#line 42 "inform7/Chapter 16/Type Checking.w"
int Specifications__Matching__can_we_match_value_descriptions(specification *from_spec, specification *to_spec) ;
#line 68 "inform7/Chapter 16/Type Checking.w"
kind * narrowest_kind_of_value_or_description(specification *spec) ;
#line 160 "inform7/Chapter 16/Type Checking.w"
int problems_issued_during_typechecking(void) ;
#line 185 "inform7/Chapter 16/Type Checking.w"
int Specifications__Matching__check_without_expectations(specification *found) ;
#line 189 "inform7/Chapter 16/Type Checking.w"
int Specifications__Matching__check(specification *found, specification *expected) ;
#line 215 "inform7/Chapter 16/Type Checking.w"
int typecheck_recursive(specification *found, specification *expected, int problem_threshold, int depth, kind **kind_of_var_to_create) ;
#line 387 "inform7/Chapter 16/Type Checking.w"
int typecheck_recursive_inner(specification *found, specification *expected, int problem_threshold, int depth, kind **kind_of_var_to_create) ;
#line 3322 "inform7/Chapter 16/Type Checking.w"
void Specifications__Matching__note_inv_token_text(specification *found) ;
#line 3339 "inform7/Chapter 16/Type Checking.w"
kind * fix_arithmetic_operand(specification *operand, int depth) ;
#line 210 "inform7/Chapter 16/Invocations.w"
invocation * Code__Invocations__new(void) ;
#line 231 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__log(invocation *inv) ;
#line 268 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_flag(invocation *inv, int flag) ;
#line 273 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__clear_flag(invocation *inv, int flag) ;
#line 278 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__test_flag(invocation *inv, int flag) ;
#line 287 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__get_group(invocation *inv) ;
#line 292 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_group(invocation *inv, int g) ;
#line 302 "inform7/Chapter 16/Invocations.w"
int inv_get_unsorted_position(invocation *inv) ;
#line 307 "inform7/Chapter 16/Invocations.w"
void inv_set_unsorted_position(invocation *inv, int n) ;
#line 317 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_word_range(invocation *inv, int w1, int w2) ;
#line 325 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_verb_conjugation(invocation *inv, verb_conjugation *vc, verb_conjugation *modal, int neg) ;
#line 336 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_adjectival_phrase(invocation *inv, adjectival_phrase *aph) ;
#line 345 "inform7/Chapter 16/Invocations.w"
invocation_token_list * itl_new(void) ;
#line 358 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_token_check_to_do(invocation *inv, int i, specification *spec) ;
#line 369 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_token_as_parsed(invocation *inv, int i, specification *spec) ;
#line 380 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_token_to_be_parsed_against(invocation *inv, int i, specification *spec) ;
#line 394 "inform7/Chapter 16/Invocations.w"
specification * Code__Invocations__get_token_check_to_do(invocation *inv, int i) ;
#line 402 "inform7/Chapter 16/Invocations.w"
specification * Code__Invocations__get_token_as_parsed(invocation *inv, int i) ;
#line 410 "inform7/Chapter 16/Invocations.w"
specification * Code__Invocations__get_token_to_be_parsed_against(invocation *inv, int i) ;
#line 418 "inform7/Chapter 16/Invocations.w"
kind * Code__Invocations__get_token_variable_kind(invocation *inv, int i) ;
#line 426 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_token_variable_kind(invocation *inv, int i, kind *K) ;
#line 434 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__get_no_tokens(invocation *inv) ;
#line 444 "inform7/Chapter 16/Invocations.w"
phrase * Code__Invocations__get_phrase_invoked(invocation *inv) ;
#line 449 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_phrase_invoked(invocation *inv, phrase *ph) ;
#line 453 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_instead_flag(invocation *inv, int t) ;
#line 462 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__get_number_tokens(invocation *inv) ;
#line 471 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_phrase_options(invocation *inv, int w1, int w2) ;
#line 483 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__get_phrase_options(invocation *inv, int *w1, int *w2) ;
#line 495 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__get_phrase_options_bitmap(invocation *inv) ;
#line 500 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_phrase_options_bitmap(invocation *inv, int further_bits) ;
#line 515 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__implies_newline(invocation *inv) ;
#line 527 "inform7/Chapter 16/Invocations.w"
invocation_list * Code__Invocations__Lists__new(void) ;
#line 536 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__Lists__append(invocation_list *to, invocation_list *from) ;
#line 545 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__Lists__add(invocation_list *invl, invocation *inv) ;
#line 556 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__Lists__length(invocation_list *invl) ;
#line 564 "inform7/Chapter 16/Invocations.w"
invocation * first_in_invocation_list(invocation_list *invl) ;
#line 579 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__Lists__sort(invocation_list *invl) ;
#line 635 "inform7/Chapter 16/Invocations.w"
int inv_comparison(const void *i1, const void *i2) ;
#line 692 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__Lists__log(invocation_list *invl) ;
#line 703 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__Lists__log_in_detail(invocation_list *invl) ;
#line 96 "inform7/Chapter 17/Properties.w"
property * Properties__obtain(int w1, int w2, int valued) ;
#line 121 "inform7/Chapter 17/Properties.w"
property * Properties__create(int w1, int w2) ;
#line 288 "inform7/Chapter 17/Properties.w"
specification * Properties__to_specification(property *prn) ;
#line 298 "inform7/Chapter 17/Properties.w"
property * Properties__from_specification(specification *spec) ;
#line 404 "inform7/Chapter 17/Properties.w"
int Properties__match_longest(int w1, int w2) ;
#line 425 "inform7/Chapter 17/Properties.w"
property * fast_property_parse(int w1, int w2) ;
#line 438 "inform7/Chapter 17/Properties.w"
property_permission * Properties__permission_list(property *prn) ;
#line 441 "inform7/Chapter 17/Properties.w"
void Properties__set_permission_list(property *prn, property_permission *pp) ;
#line 448 "inform7/Chapter 17/Properties.w"
void Properties__log(property *prn) ;
#line 459 "inform7/Chapter 17/Properties.w"
void log_basic_pname(property *prn) ;
#line 471 "inform7/Chapter 17/Properties.w"
int Properties__is_either_or(property *prn) ;
#line 474 "inform7/Chapter 17/Properties.w"
int Properties__is_value_property(property *prn) ;
#line 485 "inform7/Chapter 17/Properties.w"
int Properties__can_be_compiled(property *prn) ;
#line 494 "inform7/Chapter 17/Properties.w"
int Properties__is_shown_in_index(property *prn) ;
#line 497 "inform7/Chapter 17/Properties.w"
void Properties__exclude_from_index(property *prn) ;
#line 504 "inform7/Chapter 17/Properties.w"
void Properties__set_indexed_already_flag(property *prn, int state) ;
#line 507 "inform7/Chapter 17/Properties.w"
int Properties__get_indexed_already_flag(property *prn) ;
#line 514 "inform7/Chapter 17/Properties.w"
void Properties__offset_in_runtime_metadata_table_is(property *prn, int pos) ;
#line 517 "inform7/Chapter 17/Properties.w"
int Properties__get_offset_in_runtime_metadata_table(property *prn) ;
#line 531 "inform7/Chapter 17/Properties.w"
void Properties__set_translation(property *prn, char *t) ;
#line 542 "inform7/Chapter 17/Properties.w"
char * Properties__get_translation(property *prn) ;
#line 547 "inform7/Chapter 17/Properties.w"
int Properties__has_been_translated(property *prn) ;
#line 557 "inform7/Chapter 17/Properties.w"
void Properties__translates(int w1, int w2, parse_node *p2) ;
#line 614 "inform7/Chapter 17/Properties.w"
void Properties__alias_translations(OUTPUT_STREAM) ;
#line 629 "inform7/Chapter 17/Properties.w"
void Properties__Traverse__begin(void) ;
#line 633 "inform7/Chapter 17/Properties.w"
int Properties__Traverse__visited(property *prn) ;
#line 648 "inform7/Chapter 17/Properties.w"
possession_marker * Properties__get_possession_marker(property *prn) ;
#line 659 "inform7/Chapter 17/Properties.w"
void Properties__compile_inferred_value(OUTPUT_STREAM, inference_subject *infs, property *prn) ;
#line 676 "inform7/Chapter 17/Properties.w"
int compile_property_value_inner(OUTPUT_STREAM, inference_subject *infs, property *prn) ;
#line 57 "inform7/Chapter 17/Either-Or Properties.w"
property * Properties__EitherOr__obtain(int w1, int w2, inference_subject *infs) ;
#line 89 "inform7/Chapter 17/Either-Or Properties.w"
property * Properties__EitherOr__new_nameless(char *I6_form) ;
#line 101 "inform7/Chapter 17/Either-Or Properties.w"
void Properties__EitherOr__initialise(property *prn) ;
#line 115 "inform7/Chapter 17/Either-Or Properties.w"
void Properties__EitherOr__make_negations(property *prn, property *neg) ;
#line 145 "inform7/Chapter 17/Either-Or Properties.w"
property * Properties__EitherOr__get_negation(property *prn) ;
#line 153 "inform7/Chapter 17/Either-Or Properties.w"
int Properties__EitherOr__stored_in_negation(property *prn) ;
#line 158 "inform7/Chapter 17/Either-Or Properties.w"
void Properties__EitherOr__make_stored_in_negation(property *prn) ;
#line 169 "inform7/Chapter 17/Either-Or Properties.w"
grammar_verb * Properties__EitherOr__get_parsing_grammar(property *prn) ;
#line 174 "inform7/Chapter 17/Either-Or Properties.w"
void Properties__EitherOr__set_parsing_grammar(property *prn, grammar_verb *gv) ;
#line 179 "inform7/Chapter 17/Either-Or Properties.w"
adjectival_phrase * Properties__EitherOr__get_aph(property *prn) ;
#line 187 "inform7/Chapter 17/Either-Or Properties.w"
void Properties__EitherOr__assert(property *prn, inference_subject *owner, int parity, int certainty) ;
#line 203 "inform7/Chapter 17/Either-Or Properties.w"
int Properties__EitherOr__implemented_as_attribute(property *prn) ;
#line 209 "inform7/Chapter 17/Either-Or Properties.w"
void Properties__EitherOr__implement_as_attribute(property *prn, int state) ;
#line 225 "inform7/Chapter 17/Either-Or Properties.w"
void Properties__EitherOr__compile_value(OUTPUT_STREAM, property *prn, int val) ;
#line 230 "inform7/Chapter 17/Either-Or Properties.w"
void Properties__EitherOr__compile_default_value(OUTPUT_STREAM, property *prn) ;
#line 242 "inform7/Chapter 17/Either-Or Properties.w"
void create_adjective_from_property(property *prn, int w1, int w2, kind *K) ;
#line 251 "inform7/Chapter 17/Either-Or Properties.w"
void make_new_adjective_sense_from_property(property *prn, int w1, int w2, kind *K) ;
#line 264 "inform7/Chapter 17/Either-Or Properties.w"
adjective_meaning * Properties__EitherOr__Adjectives__parse(parse_node *q, int sense, int adj_name_w1, int adj_name_w2, int dom_name_w1, int dom_name_w2, int cond_w1, int cond_w2, int called_w1, int called_w2) ;
#line 277 "inform7/Chapter 17/Either-Or Properties.w"
int Properties__EitherOr__Adjectives__compile(property *prn, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 286 "inform7/Chapter 17/Either-Or Properties.w"
void Properties__EitherOr__Adjectives__compiling_soon(adjective_meaning *am, property *prn, int T) ;
#line 366 "inform7/Chapter 17/Either-Or Properties.w"
int Properties__EitherOr__Adjectives__assert(property *prn, inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) ;
#line 376 "inform7/Chapter 17/Either-Or Properties.w"
int Properties__EitherOr__Adjectives__index(property *prn) ;
#line 13 "inform7/Chapter 17/Valued Properties.w"
property * Properties__Valued__obtain(int w1, int w2) ;
#line 22 "inform7/Chapter 17/Valued Properties.w"
property * Properties__Valued__obtain_within_kind(int w1, int w2, kind *K) ;
#line 65 "inform7/Chapter 17/Valued Properties.w"
property * Properties__Valued__new_nameless(char *I6_form, kind *K) ;
#line 80 "inform7/Chapter 17/Valued Properties.w"
void Properties__Valued__initialise(property *prn) ;
#line 88 "inform7/Chapter 17/Valued Properties.w"
void Properties__Valued__make_setting_relation(property *prn, int w1, int w2) ;
#line 100 "inform7/Chapter 17/Valued Properties.w"
kind * Properties__Valued__kind(property *prn) ;
#line 105 "inform7/Chapter 17/Valued Properties.w"
void Properties__Valued__set_kind(property *prn, kind *K) ;
#line 140 "inform7/Chapter 17/Valued Properties.w"
void Properties__Valued__make_coincide_with_kind(property *prn, kind *K) ;
#line 148 "inform7/Chapter 17/Valued Properties.w"
int Properties__Valued__coincides_with_kind(property *prn) ;
#line 156 "inform7/Chapter 17/Valued Properties.w"
binary_predicate * Properties__Valued__get_setting_bp(property *prn) ;
#line 164 "inform7/Chapter 17/Valued Properties.w"
void Properties__Valued__set_stored_relation(property *prn, binary_predicate *bp) ;
#line 169 "inform7/Chapter 17/Valued Properties.w"
binary_predicate * Properties__Valued__get_stored_relation(property *prn) ;
#line 182 "inform7/Chapter 17/Valued Properties.w"
void Properties__Valued__now_used_for_non_typesafe_relation(property *prn) ;
#line 187 "inform7/Chapter 17/Valued Properties.w"
int Properties__Valued__is_used_for_non_typesafe_relation(property *prn) ;
#line 195 "inform7/Chapter 17/Valued Properties.w"
void Properties__Valued__assert(property *prn, inference_subject *owner, specification *val, int certainty) ;
#line 208 "inform7/Chapter 17/Valued Properties.w"
void Properties__Valued__compile_value(OUTPUT_STREAM, property *prn, specification *val) ;
#line 217 "inform7/Chapter 17/Valued Properties.w"
void Properties__Valued__compile_default_value(OUTPUT_STREAM, property *prn) ;
#line 20 "inform7/Chapter 17/Condition Properties.w"
void Properties__Valued__Conditions__initialise(property *prn) ;
#line 28 "inform7/Chapter 17/Condition Properties.w"
property * Properties__Valued__Conditions__new(inference_subject *infs, int n1, int n2, parse_node *set, int *already) ;
#line 140 "inform7/Chapter 17/Condition Properties.w"
inference_subject * Properties__Valued__Conditions__of_what(property *prn) ;
#line 23 "inform7/Chapter 17/Indefinite Appearance.w"
void Properties__Appearance__infer(inference_subject *infs, specification *spec) ;
#line 63 "inform7/Chapter 17/Indefinite Appearance.w"
void Properties__Appearance__reallocate(inference_subject *infs) ;
#line 25 "inform7/Chapter 17/The Provision Relation.w"
void Properties__Valued__Relations__Provision__create_initial_stock(void) ;
#line 38 "inform7/Chapter 17/The Provision Relation.w"
void Properties__Valued__Relations__Provision__create_second_stock(void) ;
#line 47 "inform7/Chapter 17/The Provision Relation.w"
int Properties__Valued__Relations__Provision__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 65 "inform7/Chapter 17/The Provision Relation.w"
int Properties__Valued__Relations__Provision__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 82 "inform7/Chapter 17/The Provision Relation.w"
int Properties__Valued__Relations__Provision__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 120 "inform7/Chapter 17/The Provision Relation.w"
int Properties__Valued__Relations__Provision__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 87 "inform7/Chapter 17/Measurement Adjectives.w"
binary_predicate * weak_comparison_bp(int shape) ;
#line 98 "inform7/Chapter 17/Measurement Adjectives.w"
char * Properties__Measurement__strict_comparison(int shape) ;
#line 111 "inform7/Chapter 17/Measurement Adjectives.w"
measurement_definition * Properties__Measurement__retrieve(property *prn, int shape) ;
#line 121 "inform7/Chapter 17/Measurement Adjectives.w"
void Properties__Measurement__read_property_details(measurement_definition *mdef, property **prn, int *shape) ;
#line 134 "inform7/Chapter 17/Measurement Adjectives.w"
void Properties__Measurement__validate_definitions(void) ;
#line 142 "inform7/Chapter 17/Measurement Adjectives.w"
void validate_mdef(measurement_definition *mdef) ;
#line 211 "inform7/Chapter 17/Measurement Adjectives.w"
int mdef_is_valid(measurement_definition *mdef) ;
#line 255 "inform7/Chapter 17/Measurement Adjectives.w"
adjective_meaning * Properties__Measurement__Adjectives__parse(parse_node *q, int sense, int adj_name_w1, int adj_name_w2, int dom_name_w1, int dom_name_w2, int cond_w1, int cond_w2, int called_w1, int called_w2) ;
#line 404 "inform7/Chapter 17/Measurement Adjectives.w"
void Properties__Measurement__Adjectives__compiling_soon(adjective_meaning *am, measurement_definition *mdef, int T) ;
#line 415 "inform7/Chapter 17/Measurement Adjectives.w"
int Properties__Measurement__Adjectives__compile(measurement_definition *mdef, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 420 "inform7/Chapter 17/Measurement Adjectives.w"
int Properties__Measurement__Adjectives__assert(measurement_definition *mdef, inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) ;
#line 434 "inform7/Chapter 17/Measurement Adjectives.w"
int Properties__Measurement__Adjectives__index(measurement_definition *mdef) ;
#line 441 "inform7/Chapter 17/Measurement Adjectives.w"
void Properties__Measurement__Adjectives__compile_MADJ_routines(OUTPUT_STREAM) ;
#line 479 "inform7/Chapter 17/Measurement Adjectives.w"
void Properties__Measurement__Adjectives__create_comparatives(void) ;
#line 21 "inform7/Chapter 17/Comparative Relations.w"
void Properties__Valued__Relations__Comparative__create_initial_stock(void) ;
#line 35 "inform7/Chapter 17/Comparative Relations.w"
void Properties__Valued__Relations__Comparative__create_second_stock(void) ;
#line 45 "inform7/Chapter 17/Comparative Relations.w"
int Properties__Valued__Relations__Comparative__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 72 "inform7/Chapter 17/Comparative Relations.w"
int Properties__Valued__Relations__Comparative__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 82 "inform7/Chapter 17/Comparative Relations.w"
int Properties__Valued__Relations__Comparative__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 115 "inform7/Chapter 17/Comparative Relations.w"
int Properties__Valued__Relations__Comparative__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 13 "inform7/Chapter 17/Value-Property Relations.w"
void Properties__Valued__Relations__Setting__create_initial_stock(void) ;
#line 16 "inform7/Chapter 17/Value-Property Relations.w"
void Properties__Valued__Relations__Same__create_initial_stock(void) ;
#line 27 "inform7/Chapter 17/Value-Property Relations.w"
binary_predicate * Properties__Valued__Relations__make_set_property_BP(int w1, int w2) ;
#line 44 "inform7/Chapter 17/Value-Property Relations.w"
binary_predicate * Properties__Valued__Relations__find_set_property_BP(int w1, int w2) ;
#line 57 "inform7/Chapter 17/Value-Property Relations.w"
void Properties__Valued__Relations__fix_property_bp(binary_predicate *bp) ;
#line 104 "inform7/Chapter 17/Value-Property Relations.w"
binary_predicate * Properties__Valued__Relations__make_set_nameless_property_BP(property *prn) ;
#line 117 "inform7/Chapter 17/Value-Property Relations.w"
void Properties__Valued__Relations__Setting__create_second_stock(void) ;
#line 131 "inform7/Chapter 17/Value-Property Relations.w"
void set_property_BP_schemas(binary_predicate *bp, property *prn) ;
#line 158 "inform7/Chapter 17/Value-Property Relations.w"
void Properties__Valued__Relations__Same__create_second_stock(void) ;
#line 219 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Setting__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 290 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Same__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 298 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Setting__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 305 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Same__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 315 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Setting__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 320 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Same__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 328 "inform7/Chapter 17/Value-Property Relations.w"
property * Properties__Valued__Relations__bp_get_same_as_property(binary_predicate *bp) ;
#line 331 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__bp_sets_a_property(binary_predicate *bp) ;
#line 339 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Setting__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 343 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Same__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 102 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__allocate_attributes(void) ;
#line 166 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__compile_attributes(OUTPUT_STREAM) ;
#line 250 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__begin_sequencing_objects(void) ;
#line 261 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__place_this_object_next(instance *I) ;
#line 273 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__place_objects_in_definition_sequence(void) ;
#line 300 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__compile_all(OUTPUT_STREAM) ;
#line 311 "inform7/Chapter 17/Properties of Objects.w"
void compile_class_definitions(OUTPUT_STREAM, inference_subject *within) ;
#line 324 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__compile_subject(OUTPUT_STREAM, inference_subject *subj) ;
#line 440 "inform7/Chapter 17/Properties of Objects.w"
int compile_property_within_object_body(OUTPUT_STREAM, inference_subject *know, property *prn) ;
#line 495 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__compile_has_property(OUTPUT_STREAM, property *prn) ;
#line 528 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__property_metadata_array(OUTPUT_STREAM) ;
#line 615 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__CreatePropertyOffsets_routine(OUTPUT_STREAM) ;
#line 660 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__compile_stub_properties(OUTPUT_STREAM) ;
#line 41 "inform7/Chapter 17/Properties of Values.w"
property_of_value_storage * Properties__Implementation__OfValues__get_storage(void) ;
#line 49 "inform7/Chapter 17/Properties of Values.w"
void Properties__Implementation__OfValues__pp_set_table_storage(int t, int i) ;
#line 73 "inform7/Chapter 17/Properties of Values.w"
void Properties__Implementation__OfValues__compile_properties(OUTPUT_STREAM, kind *K) ;
#line 160 "inform7/Chapter 17/Properties of Values.w"
int kind_has_a_vph(kind *K) ;
#line 186 "inform7/Chapter 17/Properties of Values.w"
int kind_no_permitted_properties(OUTPUT_STREAM, int count_only, kind *K) ;
#line 75 "inform7/Chapter 18/Introduction to the Model World.w"
void World__begin(void) ;
#line 84 "inform7/Chapter 18/Inference Subjects.w"
void infs_initialise(inference_subject *infs, general_pointer gp, int KOI, int cert, inference_subject *from, char *lname) ;
#line 110 "inform7/Chapter 18/Inference Subjects.w"
inference_subject * World__Subjects__new_fundamental(inference_subject *from, char *lname) ;
#line 116 "inform7/Chapter 18/Inference Subjects.w"
inference_subject * World__Subjects__new(inference_subject *from, int KOI, general_pointer gp, int cert) ;
#line 129 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__renew(inference_subject *infs, inference_subject *from, int KOI, general_pointer gp, int cert) ;
#line 139 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__alias_to_nonlocal_variable(inference_subject *infs, nonlocal_variable *q) ;
#line 143 "inform7/Chapter 18/Inference Subjects.w"
int World__Subjects__aliased_but_diverted(inference_subject *infs) ;
#line 163 "inform7/Chapter 18/Inference Subjects.w"
int World__Subjects__is_within(inference_subject *smaller, inference_subject *larger) ;
#line 171 "inform7/Chapter 18/Inference Subjects.w"
int World__Subjects__is_strictly_within(inference_subject *subj, inference_subject *larger) ;
#line 180 "inform7/Chapter 18/Inference Subjects.w"
inference_subject * World__Subjects__narrowest_broader_subject(inference_subject *narrow) ;
#line 191 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__falls_within(inference_subject *narrow, inference_subject *broad) ;
#line 201 "inform7/Chapter 18/Inference Subjects.w"
parse_node * World__Subjects__where_created(inference_subject *infs) ;
#line 206 "inform7/Chapter 18/Inference Subjects.w"
int World__Subjects__get_default_certainty(inference_subject *infs) ;
#line 210 "inform7/Chapter 18/Inference Subjects.w"
assemblies_data * World__Subjects__get_assemblies_data(inference_subject *infs) ;
#line 215 "inform7/Chapter 18/Inference Subjects.w"
inference * World__Subjects__get_inferences(inference_subject *infs) ;
#line 219 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__set_inferences(inference_subject *infs, inference *inf) ;
#line 224 "inform7/Chapter 18/Inference Subjects.w"
implication * World__Subjects__get_implications(inference_subject *infs) ;
#line 228 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__set_implications(inference_subject *infs, implication *imp) ;
#line 232 "inform7/Chapter 18/Inference Subjects.w"
property_permission ** World__Subjects__get_permissions(inference_subject *infs) ;
#line 241 "inform7/Chapter 18/Inference Subjects.w"
inference_subject * World__Subjects__from_specification(specification *spec) ;
#line 272 "inform7/Chapter 18/Inference Subjects.w"
specification * World__Subjects__as_constant(inference_subject *infs) ;
#line 288 "inform7/Chapter 18/Inference Subjects.w"
instance * World__Subjects__as_instance(inference_subject *infs) ;
#line 297 "inform7/Chapter 18/Inference Subjects.w"
kind * World__Subjects__as_nonobject_kind(inference_subject *infs) ;
#line 307 "inform7/Chapter 18/Inference Subjects.w"
kind * World__Subjects__as_kind(inference_subject *infs) ;
#line 316 "inform7/Chapter 18/Inference Subjects.w"
nonlocal_variable * World__Subjects__as_nlv(inference_subject *infs) ;
#line 322 "inform7/Chapter 18/Inference Subjects.w"
binary_predicate * World__Subjects__as_bp(inference_subject *infs) ;
#line 328 "inform7/Chapter 18/Inference Subjects.w"
instance * World__Subjects__as_nc(inference_subject *infs) ;
#line 337 "inform7/Chapter 18/Inference Subjects.w"
int World__Subjects__is_an_object(inference_subject *infs) ;
#line 341 "inform7/Chapter 18/Inference Subjects.w"
int World__Subjects__is_a_kind_of_object(inference_subject *infs) ;
#line 355 "inform7/Chapter 18/Inference Subjects.w"
kind * World__Subjects__domain(inference_subject *infs) ;
#line 362 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__log(inference_subject *infs) ;
#line 380 "inform7/Chapter 18/Inference Subjects.w"
void log_knowledge_about(inference_subject *infs) ;
#line 393 "inform7/Chapter 18/Inference Subjects.w"
void log_infs_hierarchy(void) ;
#line 398 "inform7/Chapter 18/Inference Subjects.w"
void log_subjects_hierarchically(inference_subject *infs, int count) ;
#line 415 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__get_name_text(inference_subject *infs, int *w1, int *w2) ;
#line 436 "inform7/Chapter 18/Inference Subjects.w"
general_pointer World__Subjects__new_permission_granted(inference_subject *infs) ;
#line 454 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__make_adj_const_domain(inference_subject *infs, instance *nc, property *prn) ;
#line 471 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__complete_model(inference_subject *infs) ;
#line 486 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__check_model(inference_subject *infs) ;
#line 506 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__write_element_of_condition(inference_subject *infs, char *cond) ;
#line 528 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__compile_all(OUTPUT_STREAM) ;
#line 114 "inform7/Chapter 18/Property Permissions.w"
property_permission * World__Permissions__find(inference_subject *infs, property *prn, int allow_inheritance) ;
#line 141 "inform7/Chapter 18/Property Permissions.w"
property_permission * World__Permissions__grant(inference_subject *infs, property *prn, int allow_inheritance) ;
#line 199 "inform7/Chapter 18/Property Permissions.w"
property * World__Permissions__get_property(property_permission *pp) ;
#line 203 "inform7/Chapter 18/Property Permissions.w"
inference_subject * World__Permissions__get_subject(property_permission *pp) ;
#line 207 "inform7/Chapter 18/Property Permissions.w"
general_pointer World__Permissions__get_storage_data(property_permission *pp) ;
#line 211 "inform7/Chapter 18/Property Permissions.w"
parse_node * World__Permissions__where_granted(property_permission *pp) ;
#line 219 "inform7/Chapter 18/Property Permissions.w"
void World__Permissions__index(property *prn) ;
#line 99 "inform7/Chapter 18/Inferences.w"
inference * create_inference(int type, int certitude) ;
#line 120 "inform7/Chapter 18/Inferences.w"
inference * create_property_inference(inference_subject *infs, property *prn, specification *val) ;
#line 132 "inform7/Chapter 18/Inferences.w"
inference * create_relation_inference(inference_subject *infs0, inference_subject *infs1) ;
#line 140 "inform7/Chapter 18/Inferences.w"
inference * create_relation_inference_spec(specification *spec0, specification *spec1) ;
#line 158 "inform7/Chapter 18/Inferences.w"
void World__Inferences__draw_property(inference_subject *infs, property *prn, specification *val) ;
#line 164 "inform7/Chapter 18/Inferences.w"
void World__Inferences__draw_negated_property(inference_subject *infs, property *prn, specification *val) ;
#line 171 "inform7/Chapter 18/Inferences.w"
void World__Inferences__draw_relation(binary_predicate *bp, inference_subject *infs0, inference_subject *infs1) ;
#line 177 "inform7/Chapter 18/Inferences.w"
void World__Inferences__draw_relation_spec(binary_predicate *bp, specification *spec0, specification *spec1) ;
#line 187 "inform7/Chapter 18/Inferences.w"
void World__Inferences__draw(int type, inference_subject *about, int certitude, inference_subject *infs0, inference_subject *infs1) ;
#line 199 "inform7/Chapter 18/Inferences.w"
int World__Inferences__get_timestamp(inference *i) ;
#line 203 "inform7/Chapter 18/Inferences.w"
int World__Inferences__get_inference_type(inference *i) ;
#line 207 "inform7/Chapter 18/Inferences.w"
parse_node * World__Inferences__where_inferred(inference *i) ;
#line 211 "inform7/Chapter 18/Inferences.w"
int World__Inferences__get_certainty(inference *i) ;
#line 215 "inform7/Chapter 18/Inferences.w"
void World__Inferences__set_certainty(inference *i, int ce) ;
#line 219 "inform7/Chapter 18/Inferences.w"
int World__Inferences__added_in_construction(inference *i) ;
#line 223 "inform7/Chapter 18/Inferences.w"
property * World__Inferences__get_property(inference *i) ;
#line 227 "inform7/Chapter 18/Inferences.w"
specification * World__Inferences__get_property_value(inference *i) ;
#line 231 "inform7/Chapter 18/Inferences.w"
specification * World__Inferences__set_property_value_kind(inference *i, kind *K) ;
#line 241 "inform7/Chapter 18/Inferences.w"
void World__Inferences__get_references(inference *i, inference_subject **infs1, inference_subject **infs2) ;
#line 246 "inform7/Chapter 18/Inferences.w"
void World__Inferences__get_references_spec(inference *i, specification **spec1, specification **spec2) ;
#line 251 "inform7/Chapter 18/Inferences.w"
instance * World__Inferences__get_reference_as_object(inference *i) ;
#line 271 "inform7/Chapter 18/Inferences.w"
int World__Inferences__get_EO_state(inference_subject *infs, property *prn) ;
#line 290 "inform7/Chapter 18/Inferences.w"
int get_EO_state_without_inheritance(inference_subject *infs, property *prn, parse_node **where) ;
#line 312 "inform7/Chapter 18/Inferences.w"
void World__Inferences__verify_prop_states(inference_subject *infs) ;
#line 336 "inform7/Chapter 18/Inferences.w"
specification * World__Inferences__get_prop_state(inference_subject *infs, property *prn) ;
#line 349 "inform7/Chapter 18/Inferences.w"
specification * World__Inferences__get_prop_state_at(inference_subject *infs, property *prn, parse_node **where) ;
#line 366 "inform7/Chapter 18/Inferences.w"
specification * World__Inferences__get_prop_state_without_inheritance(inference_subject *infs, property *prn, parse_node **where) ;
#line 385 "inform7/Chapter 18/Inferences.w"
void World__Inferences__index(inference_subject *infs, int brief) ;
#line 417 "inform7/Chapter 18/Inferences.w"
int has_or_can_have(inference_subject *infs, property *prn) ;
#line 432 "inform7/Chapter 18/Inferences.w"
void index_provided(inference_subject *infs, int bool, int c, char *cert, int brief) ;
#line 472 "inform7/Chapter 18/Inferences.w"
void World__Inferences__index_specific(inference_subject *infs) ;
#line 547 "inform7/Chapter 18/Inferences.w"
int compare_inferences(inference *i1, inference *i2) ;
#line 583 "inform7/Chapter 18/Inferences.w"
void World__Inferences__diversion_on(void) ;
#line 586 "inform7/Chapter 18/Inferences.w"
void World__Inferences__diversion_off(void) ;
#line 590 "inform7/Chapter 18/Inferences.w"
inference_subject * divert_infs(inference_subject *infs) ;
#line 612 "inform7/Chapter 18/Inferences.w"
void join_inference(inference *i, inference_subject *infs) ;
#line 803 "inform7/Chapter 18/Inferences.w"
void report_inference(inference *i, inference_subject *infs, char *what_happened) ;
#line 810 "inform7/Chapter 18/Inferences.w"
void World__Inferences__log_kind(int it) ;
#line 818 "inform7/Chapter 18/Inferences.w"
void World__Inferences__log(inference *in) ;
#line 54 "inform7/Chapter 18/Complete Model World.w"
void World__complete(void) ;
#line 210 "inform7/Chapter 18/Complete Model World.w"
void World__complete_additions(void) ;
#line 18 "inform7/Chapter 18/Compile Model World.w"
void World__Compile__set_rough_memory_usage(kind *K, int words_used) ;
#line 25 "inform7/Chapter 18/Compile Model World.w"
int World__Compile__get_rough_memory_usage(kind *K) ;
#line 36 "inform7/Chapter 18/Compile Model World.w"
void World__Compile__compile(OUTPUT_STREAM) ;
#line 39 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__start(void) ;
#line 65 "inform7/Chapter 18/The Naming Thicket.w"
int naming_new_property_notify(property *prn) ;
#line 90 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__now_has_proper_name(inference_subject *infs) ;
#line 95 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__object_now_has_proper_name(instance *I) ;
#line 101 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__object_now_has_plural_name(instance *I) ;
#line 117 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__object_takes_definite_article(inference_subject *subj) ;
#line 128 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__transfer_details(inference_subject *from, inference_subject *to) ;
#line 138 "inform7/Chapter 18/The Naming Thicket.w"
instance * object_this_is_named_after(instance *I) ;
#line 149 "inform7/Chapter 18/The Naming Thicket.w"
int Plugins__Naming__object_is_privately_named(instance *I) ;
#line 161 "inform7/Chapter 18/The Naming Thicket.w"
int naming_complete_model(int stage) ;
#line 439 "inform7/Chapter 18/The Naming Thicket.w"
int look_for_printed_name(inference_subject *subj) ;
#line 455 "inform7/Chapter 18/The Naming Thicket.w"
void compose_words_to_I6_naming_text(OUTPUT_STREAM, int w1, int w2, int cap, int your_flag) ;
#line 485 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__compile_small_names(OUTPUT_STREAM) ;
#line 38 "inform7/Chapter 18/Instance Counting.w"
void Plugins__Counting__start(void) ;
#line 49 "inform7/Chapter 18/Instance Counting.w"
int counting_new_subject_notify(inference_subject *subj) ;
#line 54 "inform7/Chapter 18/Instance Counting.w"
counting_data * counting_plugin_new_data(inference_subject *subj) ;
#line 79 "inform7/Chapter 18/Instance Counting.w"
void make_instance_counts(void) ;
#line 113 "inform7/Chapter 18/Instance Counting.w"
int Plugins__Counting__instance_count(instance *I, kind *K) ;
#line 132 "inform7/Chapter 18/Instance Counting.w"
instance * next_instance_of(instance *I, kind *k) ;
#line 150 "inform7/Chapter 18/Instance Counting.w"
specification * next_instance_of_as_value(instance *I, kind *k) ;
#line 166 "inform7/Chapter 18/Instance Counting.w"
int counting_compile_model_tables(OUTPUT_STREAM) ;
#line 207 "inform7/Chapter 18/Instance Counting.w"
int kind_of_object_count(kind *K) ;
#line 235 "inform7/Chapter 18/Instance Counting.w"
int counting_complete_model(int stage) ;
#line 337 "inform7/Chapter 18/Instance Counting.w"
int counting_estimate_property_usage(kind *k, int *words_used) ;
#line 354 "inform7/Chapter 18/Instance Counting.w"
int Plugins__Counting__optimise_loop(i6_schema *sch, kind *K) ;
#line 100 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__start(void) ;
#line 154 "inform7/Chapter 19/Spatial Model.w"
int spatial_name_to_early_infs(int w1, int w2, inference_subject **infs) ;
#line 170 "inform7/Chapter 19/Spatial Model.w"
spatial_data * spatial_plugin_new_data(inference_subject *subj) ;
#line 186 "inform7/Chapter 19/Spatial Model.w"
int spatial_log_inference_type(int it) ;
#line 198 "inform7/Chapter 19/Spatial Model.w"
int spatial_inferences_contradict(inference *A, inference *B, int similarity) ;
#line 206 "inform7/Chapter 19/Spatial Model.w"
int spatial_explain_contradiction(inference *A, inference *B, int similarity, inference_subject *subj) ;
#line 247 "inform7/Chapter 19/Spatial Model.w"
int spatial_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) ;
#line 260 "inform7/Chapter 19/Spatial Model.w"
int spatial_new_subject_notify(inference_subject *subj) ;
#line 270 "inform7/Chapter 19/Spatial Model.w"
int spatial_set_kind_notify(instance *I, kind *k) ;
#line 283 "inform7/Chapter 19/Spatial Model.w"
int spatial_set_subkind_notify(kind *sub, kind *super) ;
#line 306 "inform7/Chapter 19/Spatial Model.w"
int Plugins__Spatial__object_is_a_room(instance *I) ;
#line 317 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__get_world_size(int *rooms, int *things) ;
#line 344 "inform7/Chapter 19/Spatial Model.w"
int spatial_new_property_notify(property *prn) ;
#line 365 "inform7/Chapter 19/Spatial Model.w"
int spatial_default_appearance(inference_subject *infs, specification *txt) ;
#line 435 "inform7/Chapter 19/Spatial Model.w"
int spatial_parse_composite_NQs(int *w1, int *w2, int *determiner_w1, int *determiner_w2, quantifier **quant, kind **some_kind) ;
#line 460 "inform7/Chapter 19/Spatial Model.w"
int spatial_act_on_special_NPs(parse_node *p) ;
#line 474 "inform7/Chapter 19/Spatial Model.w"
int spatial_intervene_in_assertion(parse_node *px, parse_node *py) ;
#line 511 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__infer_presence_here(instance *I) ;
#line 532 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__infer_presence_nowhere(instance *I) ;
#line 544 "inform7/Chapter 19/Spatial Model.w"
int IF_complete_model(int stage) ;
#line 563 "inform7/Chapter 19/Spatial Model.w"
int spatial_stage_I(void) ;
#line 738 "inform7/Chapter 19/Spatial Model.w"
instance * Plugins__Spatial__progenitor(instance *I) ;
#line 744 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__set_progenitor(instance *of, instance *to, inference *reason) ;
#line 756 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__void_progenitor(instance *of) ;
#line 769 "inform7/Chapter 19/Spatial Model.w"
int spatial_stage_II(void) ;
#line 930 "inform7/Chapter 19/Spatial Model.w"
void log_object_tree(void) ;
#line 937 "inform7/Chapter 19/Spatial Model.w"
void log_object_tree_recursively(instance *I, int depth) ;
#line 955 "inform7/Chapter 19/Spatial Model.w"
void adopt_object(instance *orphan, instance *foster) ;
#line 969 "inform7/Chapter 19/Spatial Model.w"
void part_object(instance *orphan) ;
#line 1028 "inform7/Chapter 19/Spatial Model.w"
int Plugins__Spatial__encloses(instance *I1, instance *I2) ;
#line 1041 "inform7/Chapter 19/Spatial Model.w"
int spatial_stage_III(void) ;
#line 1242 "inform7/Chapter 19/Spatial Model.w"
void add_to_object_sequence(instance *I, int depth) ;
#line 1256 "inform7/Chapter 19/Spatial Model.w"
int Plugins__Spatial__get_definition_depth(instance *I) ;
#line 1268 "inform7/Chapter 19/Spatial Model.w"
int spatial_stage_IV(void) ;
#line 1289 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__index_spatial_relationship(instance *I) ;
#line 1309 "inform7/Chapter 19/Spatial Model.w"
int Plugins__Spatial__no_detail_index(instance *I) ;
#line 1317 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__index_object_further(instance *I, int depth, int details) ;
#line 1350 "inform7/Chapter 19/Spatial Model.w"
int spatial_add_to_World_index(instance *O) ;
#line 33 "inform7/Chapter 19/Spatial Relations.w"
void Plugins__Spatial__Relations__create_initial_stock(void) ;
#line 154 "inform7/Chapter 19/Spatial Relations.w"
void Plugins__Spatial__Relations__create_second_stock(void) ;
#line 161 "inform7/Chapter 19/Spatial Relations.w"
int Plugins__Spatial__Relations__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 173 "inform7/Chapter 19/Spatial Relations.w"
int Plugins__Spatial__Relations__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 258 "inform7/Chapter 19/Spatial Relations.w"
int Plugins__Spatial__Relations__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 265 "inform7/Chapter 19/Spatial Relations.w"
int Plugins__Spatial__Relations__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 35 "inform7/Chapter 19/The Player.w"
void Plugins__Player__start(void) ;
#line 58 "inform7/Chapter 19/The Player.w"
int player_new_instance_notify(instance *inst) ;
#line 68 "inform7/Chapter 19/The Player.w"
instance * Plugins__Player__get_start_room(void) ;
#line 101 "inform7/Chapter 19/The Player.w"
int player_new_quantity_notify(nonlocal_variable *nlv) ;
#line 160 "inform7/Chapter 19/The Player.w"
int player_variable_set_warning(nonlocal_variable *nlv, specification *val) ;
#line 194 "inform7/Chapter 19/The Player.w"
int player_detect_bodysnatching(inference_subject *body, int *snatcher, inference_subject **counterpart) ;
#line 222 "inform7/Chapter 19/The Player.w"
int player_irregular_genitive(inference_subject *owner, char *genitive, int *propriety) ;
#line 254 "inform7/Chapter 19/The Player.w"
int player_refine_implicit_noun(parse_node *p) ;
#line 272 "inform7/Chapter 19/The Player.w"
int player_complete_model(int stage) ;
#line 346 "inform7/Chapter 19/The Player.w"
void Plugins__Player__InitialSituation_array(OUTPUT_STREAM) ;
#line 362 "inform7/Chapter 19/The Player.w"
void Plugins__Player__index_object_further(instance *I, int depth, int details) ;
#line 368 "inform7/Chapter 19/The Player.w"
int player_annotate_in_World_index(instance *I) ;
#line 27 "inform7/Chapter 19/Backdrops.w"
void Plugins__Backdrops__start(void) ;
#line 48 "inform7/Chapter 19/Backdrops.w"
int backdrops_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) ;
#line 58 "inform7/Chapter 19/Backdrops.w"
int object_is_a_backdrop(instance *I) ;
#line 76 "inform7/Chapter 19/Backdrops.w"
int backdrops_new_property_notify(property *prn) ;
#line 82 "inform7/Chapter 19/Backdrops.w"
int Plugins__Backdrops__object_is_scenery(instance *I) ;
#line 91 "inform7/Chapter 19/Backdrops.w"
int backdrops_estimate_property_usage(kind *k, int *words_used) ;
#line 99 "inform7/Chapter 19/Backdrops.w"
int backdrops_log_inference_type(int it) ;
#line 117 "inform7/Chapter 19/Backdrops.w"
int Plugins__Backdrops__assert_relations(binary_predicate *relation, instance *I0, instance *I1) ;
#line 154 "inform7/Chapter 19/Backdrops.w"
void Plugins__Backdrops__index_object_further(instance *loc, int depth, int details, char *bef, char *aft) ;
#line 184 "inform7/Chapter 19/Backdrops.w"
int backdrops_intervene_in_assertion(parse_node *px, parse_node *py) ;
#line 211 "inform7/Chapter 19/Backdrops.w"
void Plugins__Backdrops__infer_presence_everywhere(instance *I) ;
#line 228 "inform7/Chapter 19/Backdrops.w"
int backdrops_complete_model(int stage) ;
#line 43 "inform7/Chapter 19/Regions.w"
void Plugins__Regions__start(void) ;
#line 58 "inform7/Chapter 19/Regions.w"
regions_data * regions_plugin_new_data(inference_subject *subj) ;
#line 77 "inform7/Chapter 19/Regions.w"
int regions_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) ;
#line 84 "inform7/Chapter 19/Regions.w"
int regions_new_subject_notify(inference_subject *subj) ;
#line 92 "inform7/Chapter 19/Regions.w"
int regions_set_subkind_notify(kind *sub, kind *super) ;
#line 107 "inform7/Chapter 19/Regions.w"
int Plugins__Regions__object_is_a_region(instance *I) ;
#line 119 "inform7/Chapter 19/Regions.w"
int regions_more_specific(instance *I1, instance *I2) ;
#line 145 "inform7/Chapter 19/Regions.w"
int regions_new_property_notify(property *prn) ;
#line 154 "inform7/Chapter 19/Regions.w"
int regions_estimate_property_usage(kind *k, int *words_used) ;
#line 164 "inform7/Chapter 19/Regions.w"
int regions_intervene_in_assertion(parse_node *px, parse_node *py) ;
#line 205 "inform7/Chapter 19/Regions.w"
int regions_name_to_early_infs(int w1, int w2, inference_subject **infs) ;
#line 213 "inform7/Chapter 19/Regions.w"
void Plugins__Regions__create_relations(void) ;
#line 231 "inform7/Chapter 19/Regions.w"
int Plugins__Regions__assert_relations(binary_predicate *relation, instance *I0, instance *I1) ;
#line 292 "inform7/Chapter 19/Regions.w"
instance * Plugins__Regions__enclosing(instance *reg) ;
#line 303 "inform7/Chapter 19/Regions.w"
int regions_complete_model(int stage) ;
#line 353 "inform7/Chapter 19/Regions.w"
int regions_add_to_World_index(instance *O) ;
#line 100 "inform7/Chapter 19/The Map.w"
void Plugins__Map__start(void) ;
#line 123 "inform7/Chapter 19/The Map.w"
map_data * map_plugin_new_data(inference_subject *subj) ;
#line 143 "inform7/Chapter 19/The Map.w"
int map_log_inference_type(int it) ;
#line 156 "inform7/Chapter 19/The Map.w"
int map_inferences_contradict(inference *A, inference *B, int similarity) ;
#line 178 "inform7/Chapter 19/The Map.w"
int map_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) ;
#line 191 "inform7/Chapter 19/The Map.w"
int map_set_subkind_notify(kind *sub, kind *super) ;
#line 206 "inform7/Chapter 19/The Map.w"
int map_new_subject_notify(inference_subject *subj) ;
#line 214 "inform7/Chapter 19/The Map.w"
int Plugins__Map__object_is_a_direction(instance *I) ;
#line 224 "inform7/Chapter 19/The Map.w"
int Plugins__Map__object_is_a_door(instance *I) ;
#line 239 "inform7/Chapter 19/The Map.w"
int Plugins__Map__is_a_direction(inference_subject *infs) ;
#line 263 "inform7/Chapter 19/The Map.w"
int map_set_kind_notify(instance *I, kind *k) ;
#line 313 "inform7/Chapter 19/The Map.w"
int map_compile_object_header(OUTPUT_STREAM, instance *I) ;
#line 335 "inform7/Chapter 19/The Map.w"
void build_exits_array(void) ;
#line 360 "inform7/Chapter 19/The Map.w"
int map_compile_model_tables(OUTPUT_STREAM) ;
#line 416 "inform7/Chapter 19/The Map.w"
void Plugins__Map__get_door_data(instance *door, instance **c1, instance **c2) ;
#line 434 "inform7/Chapter 19/The Map.w"
int map_new_property_notify(property *prn) ;
#line 453 "inform7/Chapter 19/The Map.w"
int map_property_value_notify(property *prn, specification *val) ;
#line 471 "inform7/Chapter 19/The Map.w"
void Plugins__Map__set_found_in(instance *I, STREAM *S) ;
#line 488 "inform7/Chapter 19/The Map.w"
instance * Plugins__Map__get_value_of_opposite_property(instance *I) ;
#line 498 "inform7/Chapter 19/The Map.w"
int map_estimate_property_usage(kind *k, int *words_used) ;
#line 515 "inform7/Chapter 19/The Map.w"
int map_act_on_special_NPs(parse_node *p) ;
#line 538 "inform7/Chapter 19/The Map.w"
int map_check_going(specification *from, specification *to, specification *by, specification *through, specification *pushing) ;
#line 571 "inform7/Chapter 19/The Map.w"
int map_intervene_in_assertion(parse_node *px, parse_node *py) ;
#line 602 "inform7/Chapter 19/The Map.w"
void Plugins__Map__enter_one_way_mode(void) ;
#line 603 "inform7/Chapter 19/The Map.w"
void Plugins__Map__exit_one_way_mode(void) ;
#line 612 "inform7/Chapter 19/The Map.w"
void Plugins__Map__connect(inference_subject *i_from, inference_subject *i_to, inference_subject *i_dir) ;
#line 637 "inform7/Chapter 19/The Map.w"
void oneway_map_connection(instance *go_from, instance *go_to, instance *forwards_dir, int certainty_level) ;
#line 654 "inform7/Chapter 19/The Map.w"
int map_complete_model(int stage) ;
#line 997 "inform7/Chapter 19/The Map.w"
int map_add_to_World_index(instance *O) ;
#line 1004 "inform7/Chapter 19/The Map.w"
int map_annotate_in_World_index(instance *O) ;
#line 25 "inform7/Chapter 19/Map Connection Relations.w"
void Plugins__Map__create_relations(void) ;
#line 38 "inform7/Chapter 19/Map Connection Relations.w"
int Plugins__Map__assert_relations(binary_predicate *relation, instance *I0, instance *I1) ;
#line 47 "inform7/Chapter 19/Map Connection Relations.w"
void Plugins__Map__Relations__create_initial_stock(void) ;
#line 58 "inform7/Chapter 19/Map Connection Relations.w"
binary_predicate * Plugins__Map__create_sketchy_mapping_direction(int w1, int w2) ;
#line 143 "inform7/Chapter 19/Map Connection Relations.w"
void Plugins__Map__Relations__make_mapped_predicate(instance *I, char *ident) ;
#line 172 "inform7/Chapter 19/Map Connection Relations.w"
void Plugins__Map__Relations__create_second_stock(void) ;
#line 180 "inform7/Chapter 19/Map Connection Relations.w"
int Plugins__Map__Relations__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 201 "inform7/Chapter 19/Map Connection Relations.w"
int Plugins__Map__Relations__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 219 "inform7/Chapter 19/Map Connection Relations.w"
int Plugins__Map__Relations__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 226 "inform7/Chapter 19/Map Connection Relations.w"
int Plugins__Map__Relations__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 234 "inform7/Chapter 19/Map Connection Relations.w"
binary_predicate * Plugins__Map__get_mapping_relation(instance *dir) ;
#line 239 "inform7/Chapter 19/Map Connection Relations.w"
instance * Plugins__Map__get_mapping_direction(binary_predicate *bp) ;
#line 61 "inform7/Chapter 19/Spatial Geometry.w"
vector Geometry__vec(int x, int y, int z) ;
#line 70 "inform7/Chapter 19/Spatial Geometry.w"
int Geometry__vec_eq(vector U, vector V) ;
#line 75 "inform7/Chapter 19/Spatial Geometry.w"
int Geometry__vec_lateral(vector V) ;
#line 83 "inform7/Chapter 19/Spatial Geometry.w"
vector Geometry__vec_plus(vector U, vector V) ;
#line 89 "inform7/Chapter 19/Spatial Geometry.w"
vector Geometry__vec_minus(vector U, vector V) ;
#line 95 "inform7/Chapter 19/Spatial Geometry.w"
vector Geometry__vec_negate(vector V) ;
#line 101 "inform7/Chapter 19/Spatial Geometry.w"
vector Geometry__vec_scale(int lambda, vector V) ;
#line 110 "inform7/Chapter 19/Spatial Geometry.w"
int Geometry__vec_length_squared(vector V) ;
#line 114 "inform7/Chapter 19/Spatial Geometry.w"
float vec_length(vector V) ;
#line 127 "inform7/Chapter 19/Spatial Geometry.w"
float Geometry__vec_angular_separation(vector E, vector D) ;
#line 140 "inform7/Chapter 19/Spatial Geometry.w"
cuboid Geometry__empty_cuboid(void) ;
#line 147 "inform7/Chapter 19/Spatial Geometry.w"
void Geometry__adjust_cuboid(cuboid *C, vector V) ;
#line 163 "inform7/Chapter 19/Spatial Geometry.w"
void Geometry__merge_cuboid(cuboid *C, cuboid X) ;
#line 179 "inform7/Chapter 19/Spatial Geometry.w"
void Geometry__cuboid_translate(cuboid *C, vector D) ;
#line 189 "inform7/Chapter 19/Spatial Geometry.w"
int Geometry__within_cuboid(vector P, cuboid C) ;
#line 206 "inform7/Chapter 19/Spatial Geometry.w"
int Geometry__cuboid_index(vector P, cuboid C) ;
#line 214 "inform7/Chapter 19/Spatial Geometry.w"
int Geometry__cuboid_volume(cuboid C) ;
#line 227 "inform7/Chapter 19/Spatial Geometry.w"
void Geometry__thicken_cuboid(cuboid *C, vector V, vector S) ;
#line 144 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__establish_spatial_coordinates(void) ;
#line 169 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__initialise_mapping_data(map_data *md) ;
#line 187 "inform7/Chapter 19/Spatial Map.w"
void set_room_position(instance *R, vector P) ;
#line 193 "inform7/Chapter 19/Spatial Map.w"
void set_room_position_breaking_cache(instance *R, vector P) ;
#line 201 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__lock_exit_in_place(instance *I, int exit, instance *I2) ;
#line 206 "inform7/Chapter 19/Spatial Map.w"
void lock_one_exit(instance *F, int exit, instance *T) ;
#line 230 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__initialise_page_directions(void) ;
#line 244 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__map_direction_as_if(instance *I, instance *I2) ;
#line 248 "inform7/Chapter 19/Spatial Map.w"
instance * Plugins__Map__mapped_as_if(instance *I) ;
#line 262 "inform7/Chapter 19/Spatial Map.w"
int Plugins__Map__direction_is_mappable(int story_direction) ;
#line 275 "inform7/Chapter 19/Spatial Map.w"
vector Plugins__Map__direction_as_vector(int story_direction) ;
#line 297 "inform7/Chapter 19/Spatial Map.w"
int Plugins__Map__opposite(int story_direction) ;
#line 321 "inform7/Chapter 19/Spatial Map.w"
int rotate_direction(int story_direction, int way) ;
#line 345 "inform7/Chapter 19/Spatial Map.w"
int Plugins__Map__direction_is_lateral(int story_direction) ;
#line 355 "inform7/Chapter 19/Spatial Map.w"
int direction_is_along_lattice(int story_direction) ;
#line 383 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__cell_position_for_direction(int story_direction, int *mx, int *my) ;
#line 406 "inform7/Chapter 19/Spatial Map.w"
char * Plugins__Map__find_icon_label(int story_direction) ;
#line 426 "inform7/Chapter 19/Spatial Map.w"
char * usual_Inform_direction_name(int story_direction) ;
#line 449 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__establish_benchmark_room(void) ;
#line 466 "inform7/Chapter 19/Spatial Map.w"
instance * Plugins__Map__room_exit(instance *origin, int dir_num, instance **via) ;
#line 486 "inform7/Chapter 19/Spatial Map.w"
instance * room_exit_as_indexed(instance *origin, int dir_num, instance **via) ;
#line 626 "inform7/Chapter 19/Spatial Map.w"
void form_spatial_relationship(instance *R, int dir, instance *T) ;
#line 642 "inform7/Chapter 19/Spatial Map.w"
instance * read_smap(instance *from, int dir) ;
#line 652 "inform7/Chapter 19/Spatial Map.w"
instance * read_smap_cross(instance *from, int dir) ;
#line 662 "inform7/Chapter 19/Spatial Map.w"
instance * read_slock(instance *from, int dir) ;
#line 672 "inform7/Chapter 19/Spatial Map.w"
connected_submap * new_submap(void) ;
#line 695 "inform7/Chapter 19/Spatial Map.w"
void add_room_to_submap(instance *R, connected_submap *sub) ;
#line 721 "inform7/Chapter 19/Spatial Map.w"
int occupied_in_submap(connected_submap *sub, vector P) ;
#line 731 "inform7/Chapter 19/Spatial Map.w"
void move_room_within_submap(connected_submap *sub, vector O, vector P) ;
#line 740 "inform7/Chapter 19/Spatial Map.w"
void add_room_to_cache(connected_submap *sub, vector P, int m) ;
#line 799 "inform7/Chapter 19/Spatial Map.w"
void free_incidence_cache(connected_submap *sub) ;
#line 809 "inform7/Chapter 19/Spatial Map.w"
void empty_submap(connected_submap *sub) ;
#line 819 "inform7/Chapter 19/Spatial Map.w"
void destroy_submap(connected_submap *sub) ;
#line 829 "inform7/Chapter 19/Spatial Map.w"
void move_component(connected_submap *sub, vector D) ;
#line 848 "inform7/Chapter 19/Spatial Map.w"
void create_submaps_from_zones(connected_submap *sub, int Z1_number, connected_submap *Zone1, int Z2_number, connected_submap *Zone2) ;
#line 865 "inform7/Chapter 19/Spatial Map.w"
void create_zones_from_submaps(connected_submap *sub, int Z1_number, connected_submap *Zone1, int Z2_number, connected_submap *Zone2) ;
#line 905 "inform7/Chapter 19/Spatial Map.w"
void create_map_component_around(instance *at) ;
#line 927 "inform7/Chapter 19/Spatial Map.w"
void translate_room(instance *R, vector D) ;
#line 931 "inform7/Chapter 19/Spatial Map.w"
void move_room_to(instance *R, vector P) ;
#line 947 "inform7/Chapter 19/Spatial Map.w"
void move_anything_locked_to(instance *R) ;
#line 955 "inform7/Chapter 19/Spatial Map.w"
void move_anything_locked_to_r(instance *R) ;
#line 974 "inform7/Chapter 19/Spatial Map.w"
void lock_positions_in_submap(connected_submap *sub) ;
#line 1022 "inform7/Chapter 19/Spatial Map.w"
void establish_natural_lengths(connected_submap *sub) ;
#line 1060 "inform7/Chapter 19/Spatial Map.w"
int heat_sum(int h1, int h2) ;
#line 1072 "inform7/Chapter 19/Spatial Map.w"
int find_submap_heat(connected_submap *sub) ;
#line 1096 "inform7/Chapter 19/Spatial Map.w"
int find_room_heat(instance *R) ;
#line 1123 "inform7/Chapter 19/Spatial Map.w"
int find_exit_heat(instance *from, int exit) ;
#line 1160 "inform7/Chapter 19/Spatial Map.w"
int exit_aligned(instance *from, int exit) ;
#line 1191 "inform7/Chapter 19/Spatial Map.w"
void position_submap(connected_submap *sub) ;
#line 1428 "inform7/Chapter 19/Spatial Map.w"
int work_out_optimal_cutpoint(connected_submap *sub, instance **from, instance **to, int *way, instance **from2, instance **to2, int *way2) ;
#line 1524 "inform7/Chapter 19/Spatial Map.w"
int 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 19/Spatial Map.w"
int 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 19/Spatial Map.w"
int divide_into_zones_onecut_r(instance *at, instance *from, instance *our_capital, instance *foreign_capital, int *borders) ;
#line 1800 "inform7/Chapter 19/Spatial Map.w"
void divide_into_zones_twocut(instance *div_F1, instance *div_T1, instance *other_F, instance *div_T2, int Z1, int Z2) ;
#line 1813 "inform7/Chapter 19/Spatial Map.w"
void divide_into_zones_twocut_r(instance *at, instance *not_X1, instance *not_Y1, instance *not_X2, instance *not_Y2) ;
#line 1853 "inform7/Chapter 19/Spatial Map.w"
void save_component_positions(connected_submap *sub) ;
#line 1859 "inform7/Chapter 19/Spatial Map.w"
void restore_component_positions(connected_submap *sub) ;
#line 1891 "inform7/Chapter 19/Spatial Map.w"
void cool_submap(connected_submap *sub) ;
#line 1929 "inform7/Chapter 19/Spatial Map.w"
void cool_component_from(connected_submap *sub, instance *R) ;
#line 2010 "inform7/Chapter 19/Spatial Map.w"
void undo_cool_exit(void) ;
#line 2015 "inform7/Chapter 19/Spatial Map.w"
void cool_exit(instance *R, int exit) ;
#line 2045 "inform7/Chapter 19/Spatial Map.w"
void quench_submap(connected_submap *sub, instance *avoid1, instance *avoid2) ;
#line 2100 "inform7/Chapter 19/Spatial Map.w"
void diffuse_submap(connected_submap *sub) ;
#line 2172 "inform7/Chapter 19/Spatial Map.w"
void diffuse_across(instance *at, instance *avoiding) ;
#line 2203 "inform7/Chapter 19/Spatial Map.w"
void radiate_submap(connected_submap *sub) ;
#line 2300 "inform7/Chapter 19/Spatial Map.w"
void radiate_across(instance *at, instance *avoiding, int not_this_way) ;
#line 2327 "inform7/Chapter 19/Spatial Map.w"
void explode_submap(connected_submap *sub) ;
#line 2519 "inform7/Chapter 19/Spatial Map.w"
int compare_components(const void *ent1, const void *ent2) ;
#line 2548 "inform7/Chapter 19/Spatial Map.w"
int component_is_adjoining(connected_submap *sub) ;
#line 2553 "inform7/Chapter 19/Spatial Map.w"
int component_is_isolated(connected_submap *sub) ;
#line 2562 "inform7/Chapter 19/Spatial Map.w"
int find_component_placement_heat(connected_submap *sub) ;
#line 2579 "inform7/Chapter 19/Spatial Map.w"
int find_cross_component_heat(connected_submap *sub) ;
#line 2585 "inform7/Chapter 19/Spatial Map.w"
void find_link_to_placed_components(connected_submap *sub, instance **outer, instance **inner) ;
#line 2590 "inform7/Chapter 19/Spatial Map.w"
int no_links_to_placed_components(connected_submap *sub) ;
#line 2594 "inform7/Chapter 19/Spatial Map.w"
int no_links_to_other_components(connected_submap *sub) ;
#line 2607 "inform7/Chapter 19/Spatial Map.w"
int cross_component_links(connected_submap *sub, instance **outer, instance **inner, int *heat, int posnd) ;
#line 2682 "inform7/Chapter 19/Spatial Map.w"
int find_cross_link_heat(instance *R, instance *S, int dir) ;
#line 2687 "inform7/Chapter 19/Spatial Map.w"
int component_metric(vector P1, vector P2, int dir) ;
#line 2748 "inform7/Chapter 19/Spatial Map.w"
void log_precis_of_map(void) ;
#line 2872 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__index_room_connections(instance *R) ;
#line 2964 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__log_spatial_layout(void) ;
#line 32 "inform7/Chapter 19/HTML Map.w"
void calculate_map_grid(void) ;
#line 197 "inform7/Chapter 19/HTML Map.w"
void correct_pair(vector P, vector D, int from_i1, int from_i2, int to_i1, int to_i2) ;
#line 274 "inform7/Chapter 19/HTML Map.w"
void correct_diagonal(vector BL, int SW_to_NE) ;
#line 347 "inform7/Chapter 19/HTML Map.w"
void begin_variable_width_table(void) ;
#line 353 "inform7/Chapter 19/HTML Map.w"
void begin_map_table(int width, int height) ;
#line 359 "inform7/Chapter 19/HTML Map.w"
void begin_variable_width_table_with_background(char *bg_image) ;
#line 368 "inform7/Chapter 19/HTML Map.w"
void end_map_table(void) ;
#line 388 "inform7/Chapter 19/HTML Map.w"
void plot_map_icon(char *icon_name) ;
#line 392 "inform7/Chapter 19/HTML Map.w"
void plot_map_icon_with_tip(char *icon_name, char *tool_tip) ;
#line 403 "inform7/Chapter 19/HTML Map.w"
void Plugins__Map__render_map_as_HTML(void) ;
#line 533 "inform7/Chapter 19/HTML Map.w"
void Plugins__Map__devise_level_rubric(int z, char **level_rubric, int *par) ;
#line 574 "inform7/Chapter 19/HTML Map.w"
void Plugins__Map__render_single_room_as_HTML(instance *R) ;
#line 599 "inform7/Chapter 19/HTML Map.w"
void plot_map_level(int x0, int x1, int y0, int y1, int z, int pass) ;
#line 871 "inform7/Chapter 19/HTML Map.w"
void plot_map_cell(int pass, vector P, int i1, int i2, int faux_exit) ;
#line 950 "inform7/Chapter 19/HTML Map.w"
void index_room_square(instance *I, int pass) ;
#line 1037 "inform7/Chapter 19/HTML Map.w"
void Plugins__Map__colour_chip(instance *I, instance *Reg, parse_node *at) ;
#line 1052 "inform7/Chapter 19/HTML Map.w"
void Plugins__Map__add_region_key(void) ;
#line 1060 "inform7/Chapter 19/HTML Map.w"
int add_key_for(instance *reg) ;
#line 158 "inform7/Chapter 19/EPS Map.w"
int get_map_variable_index(char *name) ;
#line 168 "inform7/Chapter 19/EPS Map.w"
int get_map_variable_index_forgivingly(char *name) ;
#line 181 "inform7/Chapter 19/EPS Map.w"
void Plugins__Map__prepare_map_parameter_scope(map_parameter_scope *scope) ;
#line 199 "inform7/Chapter 19/EPS Map.w"
void put_mp(char *name, map_parameter_scope *scope, instance *scope_I, kind *scope_k, char *put_string, int put_integer) ;
#line 229 "inform7/Chapter 19/EPS Map.w"
map_parameter_scope * scope_for_single_room(instance *rm) ;
#line 233 "inform7/Chapter 19/EPS Map.w"
int obj_in_region(instance *I, instance *reg) ;
#line 242 "inform7/Chapter 19/EPS Map.w"
char * get_string_mp(char *name, map_parameter_scope *scope) ;
#line 255 "inform7/Chapter 19/EPS Map.w"
void put_string_mp(char *name, map_parameter_scope *scope, char *val) ;
#line 265 "inform7/Chapter 19/EPS Map.w"
int get_int_mp(char *name, map_parameter_scope *scope) ;
#line 275 "inform7/Chapter 19/EPS Map.w"
void put_int_mp(char *name, map_parameter_scope *scope, int val) ;
#line 286 "inform7/Chapter 19/EPS Map.w"
void Plugins__Map__traverse_for_map_parameters(int pass) ;
#line 494 "inform7/Chapter 19/EPS Map.w"
void new_map_hint_sentence(int pass, parse_node *p) ;
#line 775 "inform7/Chapter 19/EPS Map.w"
int parse_eps_map_offset(char *original) ;
#line 802 "inform7/Chapter 19/EPS Map.w"
void Plugins__Map__render_map_as_EPS(void) ;
#line 884 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_map(OUTPUT_STREAM) ;
#line 1154 "inform7/Chapter 19/EPS Map.w"
void 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 1222 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_header(OUTPUT_STREAM, int bounding_box_width, int bounding_box_height, char *default_font, int default_point_size) ;
#line 1236 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_circular_path(OUTPUT_STREAM, int x0, int y0, int radius) ;
#line 1243 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_rectangular_path(OUTPUT_STREAM, int x0, int y0, int x1, int y1) ;
#line 1254 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_room_boundary_path(OUTPUT_STREAM, int bx, int by, int boxsize, char *shape) ;
#line 1268 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_horizontal_line_path(OUTPUT_STREAM, int x0, int x1, int y) ;
#line 1277 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_dashed_arrow(OUTPUT_STREAM, int length, vector Dir, int x0, int y0) ;
#line 1291 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_Bezier_curve(OUTPUT_STREAM, int stiffness0, int stiffness1, int x0, int y0, int exit0, int x1, int y1, int exit1) ;
#line 1309 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_line_width_setting(OUTPUT_STREAM, int new) ;
#line 1314 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_line_width_unsetting(OUTPUT_STREAM) ;
#line 1322 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_text(OUTPUT_STREAM, char *text, int x, int y, char *font, int pointsize, int centre_h, int centre_v) ;
#line 1341 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_set_colour(OUTPUT_STREAM, char *htmlcolour) ;
#line 1349 "inform7/Chapter 19/EPS Map.w"
void choose_colour_beam(OUTPUT_STREAM, char hex1, char hex2) ;
#line 1354 "inform7/Chapter 19/EPS Map.w"
int hex_to_int(char hex) ;
#line 1380 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_set_greyscale(OUTPUT_STREAM, int N) ;
#line 16 "inform7/Chapter 19/Showme Command.w"
void Plugins__Showme__start(void) ;
#line 31 "inform7/Chapter 19/Showme Command.w"
void Plugins__Showme__compile_SHOWME_details(OUTPUT_STREAM) ;
#line 37 "inform7/Chapter 19/Showme Command.w"
void compile_SHOWME_type(OUTPUT_STREAM, int val) ;
#line 47 "inform7/Chapter 19/Showme Command.w"
void compile_SHOWME_type_subj(OUTPUT_STREAM, int val, inference_subject *subj) ;
#line 98 "inform7/Chapter 19/Showme Command.w"
int is_property_worth_SHOWME(OUTPUT_STREAM, inference_subject *subj, property *prn) ;
#line 102 "inform7/Chapter 19/Showme Command.w"
void compile_property_SHOWME(OUTPUT_STREAM, inference_subject *subj, property *prn) ;
#line 109 "inform7/Chapter 19/Showme Command.w"
int SHOWME_primitive(OUTPUT_STREAM, inference_subject *subj, property *prn, int comp) ;
#line 100 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__start(void) ;
#line 109 "inform7/Chapter 19/Scenes.w"
int scenes_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) ;
#line 127 "inform7/Chapter 19/Scenes.w"
int scenes_new_property_notify(property *prn) ;
#line 140 "inform7/Chapter 19/Scenes.w"
int scenes_new_named_instance_notify(instance *I) ;
#line 153 "inform7/Chapter 19/Scenes.w"
void new_scene(instance *I) ;
#line 194 "inform7/Chapter 19/Scenes.w"
scene * Plugins__Scenes__from_named_constant(instance *I) ;
#line 202 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__get_name(scene *sc, int *w1, int *w2) ;
#line 209 "inform7/Chapter 19/Scenes.w"
int parse_scene_end_name(scene *sc, int en1, int en2, int create) ;
#line 243 "inform7/Chapter 19/Scenes.w"
void new_scene_rulebook(scene *sc, int end) ;
#line 322 "inform7/Chapter 19/Scenes.w"
void begins_or_ends_when(parse_node *p) ;
#line 450 "inform7/Chapter 19/Scenes.w"
void new_scene_anchor(parse_node *p) ;
#line 566 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__DetectSceneChange_routine(OUTPUT_STREAM) ;
#line 604 "inform7/Chapter 19/Scenes.w"
void test_scene_end(OUTPUT_STREAM, scene *sc, int end) ;
#line 662 "inform7/Chapter 19/Scenes.w"
void compile_scene_end(OUTPUT_STREAM, scene *sc, int end) ;
#line 677 "inform7/Chapter 19/Scenes.w"
void compile_scene_end_dash(OUTPUT_STREAM, scene *sc, int end) ;
#line 790 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__ShowSceneStatus_routine(OUTPUT_STREAM) ;
#line 837 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__PrintSceneName_routine(OUTPUT_STREAM) ;
#line 883 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__test_during_clause(OUTPUT_STREAM, specification *spec) ;
#line 20 "inform7/Chapter 19/Temporal Map.w"
void Plugins__Scenes__index(void) ;
#line 32 "inform7/Chapter 19/Temporal Map.w"
void Plugins__Scenes__index_rules(void) ;
#line 260 "inform7/Chapter 19/Temporal Map.w"
void index_from_scene(scene *sc, int depth, int end, scene *sc_from, scene **sorted, int nr) ;
#line 347 "inform7/Chapter 19/Temporal Map.w"
void scene_icon(char *si) ;
#line 351 "inform7/Chapter 19/Temporal Map.w"
void scene_icon_append(char *si) ;
#line 355 "inform7/Chapter 19/Temporal Map.w"
void scene_icon_legend(char *si, char *gloss) ;
#line 359 "inform7/Chapter 19/Temporal Map.w"
void scene_icon_unspaced(char *si) ;
#line 368 "inform7/Chapter 19/Temporal Map.w"
int compare_scenes(const void *ent1, const void *ent2) ;
#line 94 "inform7/Chapter 20/Text Literals.w"
void Data__Strings__suppress_quote_expansion(int w1) ;
#line 102 "inform7/Chapter 20/Text Literals.w"
literal_text * lt_new(int w1, int colour) ;
#line 121 "inform7/Chapter 20/Text Literals.w"
int lt_cmp(int w1, literal_text *lt) ;
#line 130 "inform7/Chapter 20/Text Literals.w"
void Data__Strings__mark_as_unescaped(literal_text *lt) ;
#line 137 "inform7/Chapter 20/Text Literals.w"
literal_text * Data__Strings__compile_literal(OUTPUT_STREAM, int w1) ;
#line 222 "inform7/Chapter 20/Text Literals.w"
literal_text * rotate(int w1, literal_text *y) ;
#line 246 "inform7/Chapter 20/Text Literals.w"
void Data__Strings__compile_quotation(OUTPUT_STREAM, int w1) ;
#line 255 "inform7/Chapter 20/Text Literals.w"
literal_text * Data__Strings__compile_literal_from_text(OUTPUT_STREAM, char *p) ;
#line 268 "inform7/Chapter 20/Text Literals.w"
void Data__Strings__compile(OUTPUT_STREAM) ;
#line 272 "inform7/Chapter 20/Text Literals.w"
void traverse_lts(OUTPUT_STREAM, literal_text *lt) ;
#line 318 "inform7/Chapter 20/Text Literals.w"
void Data__Strings__compile_small_block(OUTPUT_STREAM, literal_text *lt) ;
#line 324 "inform7/Chapter 20/Text Literals.w"
literal_text * Data__Strings__compile_literal_sb(OUTPUT_STREAM, int w1) ;
#line 67 "inform7/Chapter 20/Text Substitutions.w"
text_substitution * Data__Strings__new_text_substitution(int wn, ph_stack_frame *phsf, rule *R, int marker) ;
#line 112 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__allow_no_further_text_subs(void) ;
#line 120 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__text_substitution_name(OUTPUT_STREAM, text_substitution *ts) ;
#line 134 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__text_substitution_cue(OUTPUT_STREAM, int wn) ;
#line 177 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__append_text_substitution_proviso(void) ;
#line 211 "inform7/Chapter 20/Text Substitutions.w"
int Data__Strings__compilation_coroutine(OUTPUT_STREAM, int in_response_mode) ;
#line 240 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__compile_single_substitution(OUTPUT_STREAM, text_substitution *ts) ;
#line 320 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__compile_text_routines_in_response_mode(OUTPUT_STREAM) ;
#line 34 "inform7/Chapter 20/Responses.w"
void response_launcher_name(OUTPUT_STREAM, response_message *resp) ;
#line 42 "inform7/Chapter 20/Responses.w"
void Data__Strings__compile_response_constant(OUTPUT_STREAM, rule *R, int marker) ;
#line 65 "inform7/Chapter 20/Responses.w"
response_message * Data__Strings__response_cue(OUTPUT_STREAM, rule *owner, int marker, int wn, ph_stack_frame *phsf, int via_I6) ;
#line 85 "inform7/Chapter 20/Responses.w"
void Data__Strings__compile_response_launchers(OUTPUT_STREAM) ;
#line 165 "inform7/Chapter 20/Responses.w"
void Data__Strings__compile_responses(OUTPUT_STREAM) ;
#line 284 "inform7/Chapter 20/Responses.w"
ph_stack_frame * Data__Strings__frame_for_response(response_message *resp) ;
#line 293 "inform7/Chapter 20/Responses.w"
void Data__Strings__assert_response_value(rule *R, int marker, int wn) ;
#line 301 "inform7/Chapter 20/Responses.w"
void Data__Strings__index_response(rule *R, int marker, response_message *resp) ;
#line 328 "inform7/Chapter 20/Responses.w"
int Data__Strings__get_marker_from_response_spec(specification *rs) ;
#line 352 "inform7/Chapter 20/Responses.w"
void Data__Strings__compile_general(OUTPUT_STREAM, specification *str) ;
#line 71 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable * Data__NonlocalVariables__new_global(int w1, int w2, kind *K) ;
#line 76 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable * Data__NonlocalVariables__new_stacked(int w1, int w2, kind *K, stacked_variable *scope) ;
#line 85 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable * new_nonlocal_variable(int w1, int w2, kind *K, stacked_variable *scope) ;
#line 155 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__log(nonlocal_variable *nlv) ;
#line 166 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable * Data__NonlocalVariables__parse(int w1, int w2) ;
#line 181 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__translates(int w1, int w2, parse_node *p2) ;
#line 210 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__set_I6_identifier(nonlocal_variable *nlv, char *rvalue, char *lvalue) ;
#line 222 "inform7/Chapter 20/Nonlocal Variables.w"
char * Data__NonlocalVariables__identifier(nonlocal_variable *nlv) ;
#line 227 "inform7/Chapter 20/Nonlocal Variables.w"
char * Data__NonlocalVariables__lvalue_identifier(nonlocal_variable *nlv) ;
#line 236 "inform7/Chapter 20/Nonlocal Variables.w"
void allocate_nlv_storage(void) ;
#line 256 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__set_write_schema(nonlocal_variable *nlv, char *sch) ;
#line 260 "inform7/Chapter 20/Nonlocal Variables.w"
char * Data__NonlocalVariables__get_write_schema(nonlocal_variable *nlv) ;
#line 266 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__warn_about_change(nonlocal_variable *nlv) ;
#line 286 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__Subjects__get_name_text(inference_subject *from, int *w1, int *w2) ;
#line 291 "inform7/Chapter 20/Nonlocal Variables.w"
general_pointer Data__NonlocalVariables__Subjects__new_permission_granted(inference_subject *from) ;
#line 295 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__Subjects__make_adj_const_domain(inference_subject *infs, instance *nc, property *prn) ;
#line 299 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__Subjects__complete_model(inference_subject *infs) ;
#line 302 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__Subjects__check_model(inference_subject *infs) ;
#line 305 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__Subjects__write_element_of_condition(inference_subject *infs, char *cond) ;
#line 309 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__Subjects__compile(OUTPUT_STREAM, inference_subject *infs) ;
#line 312 "inform7/Chapter 20/Nonlocal Variables.w"
inference_subject * Data__NonlocalVariables__get_knowledge(nonlocal_variable *nlv) ;
#line 320 "inform7/Chapter 20/Nonlocal Variables.w"
int Data__NonlocalVariables__Subjects__compile_all(OUTPUT_STREAM) ;
#line 383 "inform7/Chapter 20/Nonlocal Variables.w"
specification * Data__NonlocalVariables__get_initial_value(nonlocal_variable *nlv) ;
#line 392 "inform7/Chapter 20/Nonlocal Variables.w"
parse_node * Data__NonlocalVariables__origin_of_initial_value(nonlocal_variable *nlv) ;
#line 401 "inform7/Chapter 20/Nonlocal Variables.w"
int Data__NonlocalVariables__has_initial_value_set(nonlocal_variable *nlv) ;
#line 409 "inform7/Chapter 20/Nonlocal Variables.w"
int Data__NonlocalVariables__is_global(nonlocal_variable *nlv) ;
#line 419 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__set_kind(nonlocal_variable *nlv, kind *K) ;
#line 424 "inform7/Chapter 20/Nonlocal Variables.w"
kind * Data__NonlocalVariables__kind(nonlocal_variable *nlv) ;
#line 432 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable * Data__NonlocalVariables__temporary(char *I6_form, kind *K) ;
#line 440 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable * Data__NonlocalVariables__temporary_formal(int i) ;
#line 459 "inform7/Chapter 20/Nonlocal Variables.w"
int Data__NonlocalVariables__treat_as_plain_text_word(nonlocal_variable *nlv) ;
#line 473 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__make_constant(nonlocal_variable *nlv, int bib) ;
#line 480 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__make_initalisable(nonlocal_variable *nlv) ;
#line 484 "inform7/Chapter 20/Nonlocal Variables.w"
int Data__NonlocalVariables__is_constant(nonlocal_variable *nlv) ;
#line 489 "inform7/Chapter 20/Nonlocal Variables.w"
int Data__NonlocalVariables__must_be_constant(nonlocal_variable *nlv) ;
#line 503 "inform7/Chapter 20/Nonlocal Variables.w"
specification * Data__NonlocalVariables__substitute_constants(specification *spec) ;
#line 523 "inform7/Chapter 20/Nonlocal Variables.w"
inference_subject * Data__NonlocalVariables__get_alias(nonlocal_variable *nlv) ;
#line 533 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__set_alias(nonlocal_variable *nlv, inference_subject *infs) ;
#line 549 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__compile_initial_value(OUTPUT_STREAM, nonlocal_variable *nlv) ;
#line 556 "inform7/Chapter 20/Nonlocal Variables.w"
void compile_nonlocal_variable_initial_inner(OUTPUT_STREAM, nonlocal_variable *nlv) ;
#line 635 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__index_all(void) ;
#line 677 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__index_single(nonlocal_variable *nlv) ;
#line 29 "inform7/Chapter 20/Interactive Fiction ID.w"
char * Plugins__Bibliographic__read_uuid(void) ;
#line 57 "inform7/Chapter 20/Interactive Fiction ID.w"
void Plugins__Bibliographic__UUID_ARRAY_array(OUTPUT_STREAM) ;
#line 41 "inform7/Chapter 20/Bibliographic Data.w"
void Plugins__Bibliographic__start(void) ;
#line 72 "inform7/Chapter 20/Bibliographic Data.w"
int bibliographic_new_variable_notify(nonlocal_variable *q) ;
#line 105 "inform7/Chapter 20/Bibliographic Data.w"
natural_language * Plugins__Bibliographic__scan_language(parse_node *PN) ;
#line 120 "inform7/Chapter 20/Bibliographic Data.w"
void bibliographic_data(parse_node *PN) ;
#line 177 "inform7/Chapter 20/Bibliographic Data.w"
int Plugins__Bibliographic__story_author_is(char *p) ;
#line 233 "inform7/Chapter 20/Bibliographic Data.w"
void set_episode_data(parse_node *pn) ;
#line 249 "inform7/Chapter 20/Bibliographic Data.w"
void Plugins__Bibliographic__compile_constants(OUTPUT_STREAM) ;
#line 321 "inform7/Chapter 20/Bibliographic Data.w"
void Plugins__Bibliographic__index_library_card(void) ;
#line 346 "inform7/Chapter 20/Bibliographic Data.w"
void library_card_entry(char *field, nonlocal_variable *nlv, char *t) ;
#line 363 "inform7/Chapter 20/Bibliographic Data.w"
void Plugins__Bibliographic__contents_heading(void) ;
#line 376 "inform7/Chapter 20/Bibliographic Data.w"
void index_bibliographic_variable(nonlocal_variable *nlv, char *t) ;
#line 118 "inform7/Chapter 20/Release Instructions.w"
void handle_release_declaration(parse_node *p) ;
#line 122 "inform7/Chapter 20/Release Instructions.w"
void handle_release_declaration_inner(parse_node *p) ;
#line 263 "inform7/Chapter 20/Release Instructions.w"
auxiliary_file * Plugins__Bibliographic__create_aux_file(char *leafname, char *desc, char *subfolder, int payload) ;
#line 281 "inform7/Chapter 20/Release Instructions.w"
void Plugins__Bibliographic__write_ifiction_and_blurb(void) ;
#line 534 "inform7/Chapter 20/Release Instructions.w"
void write_ifiction_record(OUTPUT_STREAM, char *header, int cover_picture_number, char *cover_art_format, unsigned int height, unsigned int width) ;
#line 757 "inform7/Chapter 20/Release Instructions.w"
int write_var_to_XML(OUTPUT_STREAM, nonlocal_variable *nlv, int desc_mode) ;
#line 794 "inform7/Chapter 20/Release Instructions.w"
void write_release_blurb(OUTPUT_STREAM, char *materials_folder, int cover_picture_number, char *cover_art_format) ;
#line 76 "inform7/Chapter 20/List Constants.w"
literal_list * empty_literal_list(int w1, int w2) ;
#line 97 "inform7/Chapter 20/List Constants.w"
literal_list * find_list_at(int incipit) ;
#line 110 "inform7/Chapter 20/List Constants.w"
literal_list * add_to_ll(specification *spec, literal_list *ll, int w1, int w2, int bad) ;
#line 129 "inform7/Chapter 20/List Constants.w"
kind * kind_of_ll(literal_list *ll, int issue_problems) ;
#line 232 "inform7/Chapter 20/List Constants.w"
kind * Data__Lists__kind_of_list_at(int incipit) ;
#line 238 "inform7/Chapter 20/List Constants.w"
void Data__Lists__check_one(int incipit) ;
#line 246 "inform7/Chapter 20/List Constants.w"
void Data__Lists__check(OUTPUT_STREAM) ;
#line 259 "inform7/Chapter 20/List Constants.w"
void Data__Lists__compile_literal_list(OUTPUT_STREAM, int incipit) ;
#line 272 "inform7/Chapter 20/List Constants.w"
void Data__Lists__compile(OUTPUT_STREAM) ;
#line 318 "inform7/Chapter 20/List Constants.w"
void Data__Lists__compile_default_list(OUTPUT_STREAM, char *identifier, kind *K) ;
#line 64 "inform7/Chapter 20/Table Columns.w"
table_column * new_table_column(int w1, int w2) ;
#line 83 "inform7/Chapter 20/Table Columns.w"
void Data__Tables__Columns__log(table_column *tc) ;
#line 93 "inform7/Chapter 20/Table Columns.w"
specification * Data__Tables__Columns__to_specification(table_column *tc) ;
#line 100 "inform7/Chapter 20/Table Columns.w"
table_column * Data__Tables__Columns__from_specification(specification *spec) ;
#line 120 "inform7/Chapter 20/Table Columns.w"
kind * Data__Tables__Columns__get_kind(table_column *tc) ;
#line 124 "inform7/Chapter 20/Table Columns.w"
void Data__Tables__Columns__set_kind(table_column *tc, table *t, kind *K) ;
#line 151 "inform7/Chapter 20/Table Columns.w"
binary_predicate * Data__Tables__Columns__get_listed_in_predicate(table_column *tc) ;
#line 163 "inform7/Chapter 20/Table Columns.w"
int Data__Tables__Columns__get_id(table_column *tc) ;
#line 167 "inform7/Chapter 20/Table Columns.w"
void Data__Tables__Columns__compile_run_time_support(OUTPUT_STREAM) ;
#line 192 "inform7/Chapter 20/Table Columns.w"
table_column_usage Data__Tables__Columns__add_to_table(int w1, int w2, table *t) ;
#line 280 "inform7/Chapter 20/Table Columns.w"
table_column * find_table_column(int w1, int w2, table *t, int *exp1, int *exp2) ;
#line 329 "inform7/Chapter 20/Table Columns.w"
void Data__Tables__Columns__check_explicit_headings(table *t, int i, table_column_usage *tcu) ;
#line 376 "inform7/Chapter 20/Table Columns.w"
void Data__Tables__Columns__note_kind(table *t, int i, table_column_usage *tcu, parse_node *cell, kind *K, int generic) ;
#line 509 "inform7/Chapter 20/Table Columns.w"
void Data__Tables__Columns__approve_kind(table *t, int i, table_column_usage *tcu) ;
#line 83 "inform7/Chapter 20/Tables.w"
void Data__Tables__traverse_to_create(void) ;
#line 97 "inform7/Chapter 20/Tables.w"
void Data__Tables__traverse_to_stock(void) ;
#line 113 "inform7/Chapter 20/Tables.w"
void Data__Tables__check_tables_for_kind_clashes(void) ;
#line 136 "inform7/Chapter 20/Tables.w"
table * new_table_structure(void) ;
#line 162 "inform7/Chapter 20/Tables.w"
void add_table_contribution(table *t, parse_node *src) ;
#line 174 "inform7/Chapter 20/Tables.w"
void Data__Tables__log(table *t) ;
#line 181 "inform7/Chapter 20/Tables.w"
int Data__Tables__get_no_columns(table *t) ;
#line 185 "inform7/Chapter 20/Tables.w"
int Data__Tables__get_no_rows(table *t) ;
#line 195 "inform7/Chapter 20/Tables.w"
int Data__Tables__expand_block_constants(table *t) ;
#line 201 "inform7/Chapter 20/Tables.w"
kind * Data__Tables__kind_of_ith_column(table *t, int i) ;
#line 210 "inform7/Chapter 20/Tables.w"
char * Data__Tables__identifier(table *t) ;
#line 214 "inform7/Chapter 20/Tables.w"
parse_node * Data__Tables__get_headline(table *t) ;
#line 301 "inform7/Chapter 20/Tables.w"
void create_table(parse_node *PN) ;
#line 812 "inform7/Chapter 20/Tables.w"
void stock_table(table *t, int phase) ;
#line 970 "inform7/Chapter 20/Tables.w"
void stock_table_cell(table *t, parse_node *cell, int row_count, int col_count) ;
#line 1051 "inform7/Chapter 20/Tables.w"
void Data__Tables__complete(void) ;
#line 1101 "inform7/Chapter 20/Tables.w"
void amend_table(table *main_table, table *amendments) ;
#line 1278 "inform7/Chapter 20/Tables.w"
void splice_table_row(table *table_to, table *table_from, int row_to, int row_from) ;
#line 1302 "inform7/Chapter 20/Tables.w"
void Data__Tables__index(void) ;
#line 1319 "inform7/Chapter 20/Tables.w"
int index_tables_in(extension_file *ef, int efc) ;
#line 1422 "inform7/Chapter 20/Tables.w"
int table_within(table *t, extension_file *ef) ;
#line 16 "inform7/Chapter 20/Runtime Support for Tables.w"
void Data__Tables__compile(OUTPUT_STREAM) ;
#line 288 "inform7/Chapter 20/Runtime Support for Tables.w"
void Data__Tables__compile_print_table_names(OUTPUT_STREAM) ;
#line 319 "inform7/Chapter 20/Runtime Support for Tables.w"
void Data__Tables__compile_max_score(OUTPUT_STREAM) ;
#line 107 "inform7/Chapter 20/Tables of Definitions.w"
void kind_defined_by_table(parse_node *pn) ;
#line 12 "inform7/Chapter 20/Listed-In Relations.w"
void Data__Tables__Relations__create_initial_stock(void) ;
#line 28 "inform7/Chapter 20/Listed-In Relations.w"
binary_predicate * Data__Tables__Relations__make_listed_in_predicate(table_column *tc) ;
#line 48 "inform7/Chapter 20/Listed-In Relations.w"
void Data__Tables__Relations__supply_kind_for_listed_in_tc(binary_predicate *bp, kind *K) ;
#line 57 "inform7/Chapter 20/Listed-In Relations.w"
void Data__Tables__Relations__create_second_stock(void) ;
#line 63 "inform7/Chapter 20/Listed-In Relations.w"
int Data__Tables__Relations__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 72 "inform7/Chapter 20/Listed-In Relations.w"
int Data__Tables__Relations__assert(binary_predicate *bp, inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) ;
#line 84 "inform7/Chapter 20/Listed-In Relations.w"
int Data__Tables__Relations__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 92 "inform7/Chapter 20/Listed-In Relations.w"
int Data__Tables__Relations__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 132 "inform7/Chapter 21/Equations.w"
void Data__Equations__traverse_to_create(void) ;
#line 159 "inform7/Chapter 21/Equations.w"
equation * Data__Equations__new(int w1, int w2, int anonymous) ;
#line 278 "inform7/Chapter 21/Equations.w"
void Data__Equations__set_wherewithal(equation *eqn, int w1, int w2) ;
#line 287 "inform7/Chapter 21/Equations.w"
void Data__Equations__traverse_to_stock(void) ;
#line 302 "inform7/Chapter 21/Equations.w"
void Data__Equations__examine(equation *eqn) ;
#line 329 "inform7/Chapter 21/Equations.w"
int eqn_declare_symbols(equation *eqn) ;
#line 456 "inform7/Chapter 21/Equations.w"
int eqn_declare_variables_inner(equation *eqn, int w1, int w2, int temp) ;
#line 465 "inform7/Chapter 21/Equations.w"
int eqn_dec_var(equation *eqn, int wn, int X, void *XP) ;
#line 544 "inform7/Chapter 21/Equations.w"
void eqn_remove_temp_variables(equation *eqn) ;
#line 566 "inform7/Chapter 21/Equations.w"
void Data__Equations__declare_local_variables(equation *eqn) ;
#line 571 "inform7/Chapter 21/Equations.w"
void Data__Equations__declare_local(equation *eqn, int w1, int w2, kind *K) ;
#line 583 "inform7/Chapter 21/Equations.w"
void eqn_declare_standard_symbols(void) ;
#line 610 "inform7/Chapter 21/Equations.w"
equation_symbol * eqn_add_symbol(equation *eqn, int w1, kind *K, specification *spec) ;
#line 648 "inform7/Chapter 21/Equations.w"
int equation_symbol_legal(int w1, int w2) ;
#line 670 "inform7/Chapter 21/Equations.w"
equation_node * enode_new(int t) ;
#line 687 "inform7/Chapter 21/Equations.w"
equation_node * enode_new_op(int op) ;
#line 693 "inform7/Chapter 21/Equations.w"
equation_node * enode_new_symbol(equation_symbol *ev) ;
#line 699 "inform7/Chapter 21/Equations.w"
equation_node * enode_new_constant(specification *spec) ;
#line 709 "inform7/Chapter 21/Equations.w"
void log_equation_node(equation_node *tok) ;
#line 713 "inform7/Chapter 21/Equations.w"
void log_equation_node_inner(equation_node *tok, int d) ;
#line 756 "inform7/Chapter 21/Equations.w"
equation_node * eqn_parse(equation *eqn) ;
#line 953 "inform7/Chapter 21/Equations.w"
int multiplication_is_implied(equation_node *previous_token, equation_node *token) ;
#line 966 "inform7/Chapter 21/Equations.w"
int application_is_implied(equation_node *previous_token, equation_node *token) ;
#line 999 "inform7/Chapter 21/Equations.w"
void log_sr_stacks(void) ;
#line 1014 "inform7/Chapter 21/Equations.w"
void enode_sr_start(void) ;
#line 1024 "inform7/Chapter 21/Equations.w"
equation_node * enode_sr_result(void) ;
#line 1048 "inform7/Chapter 21/Equations.w"
int enode_sr_token(equation *eqn, equation_node *tok) ;
#line 1100 "inform7/Chapter 21/Equations.w"
int enode_emit(equation_node *tok) ;
#line 1140 "inform7/Chapter 21/Equations.w"
int enode_lt(equation_node *tok1, equation_node *tok2) ;
#line 1145 "inform7/Chapter 21/Equations.w"
int enode_eq(equation_node *tok1, equation_node *tok2) ;
#line 1150 "inform7/Chapter 21/Equations.w"
int enode_gt(equation_node *tok1, equation_node *tok2) ;
#line 1167 "inform7/Chapter 21/Equations.w"
int f_function(equation_node *tok) ;
#line 1191 "inform7/Chapter 21/Equations.w"
int g_function(equation_node *tok) ;
#line 1218 "inform7/Chapter 21/Equations.w"
int eqn_typecheck(equation *eqn) ;
#line 1250 "inform7/Chapter 21/Equations.w"
int enode_count_equals(equation_node *tok) ;
#line 1260 "inform7/Chapter 21/Equations.w"
int enode_is_equals(equation_node *tok) ;
#line 1275 "inform7/Chapter 21/Equations.w"
int enode_typecheck(equation *eqn, equation_node *tok) ;
#line 1502 "inform7/Chapter 21/Equations.w"
void promote_subequation(equation *eqn, equation_node *tok, int deeply) ;
#line 1512 "inform7/Chapter 21/Equations.w"
void demote_subequation(equation *eqn, equation_node *tok) ;
#line 1523 "inform7/Chapter 21/Equations.w"
void Data__Equations__compile(OUTPUT_STREAM) ;
#line 1535 "inform7/Chapter 21/Equations.w"
char * Data__Equations__identifier(equation *eqn) ;
#line 1546 "inform7/Chapter 21/Equations.w"
void Data__Equations__set_usage_notes(equation *eqn, int u1, int u2) ;
#line 1555 "inform7/Chapter 21/Equations.w"
void Data__Equations__compile_solution(OUTPUT_STREAM, int w1, int w2, equation *eqn) ;
#line 1568 "inform7/Chapter 21/Equations.w"
void compile_solution_inner(OUTPUT_STREAM, int w1, int w2, equation *eqn) ;
#line 1719 "inform7/Chapter 21/Equations.w"
void enode_compile(OUTPUT_STREAM, equation *eqn, equation_node *tok) ;
#line 1769 "inform7/Chapter 21/Equations.w"
void enode_compilation_error(equation *eqn, equation_node *tok) ;
#line 1797 "inform7/Chapter 21/Equations.w"
int eqn_rearrange(equation *eqn, equation_symbol *to_solve) ;
#line 2060 "inform7/Chapter 21/Equations.w"
int enode_count_var(equation_node *tok, equation_symbol *to_solve) ;
#line 2075 "inform7/Chapter 21/Equations.w"
void Data__Equations__internal_test(int e1, int e2) ;
#line 2103 "inform7/Chapter 21/Equations.w"
void Data__Equations__log(equation *eqn) ;
#line 2107 "inform7/Chapter 21/Equations.w"
void log_equation_parsed(equation *eqn) ;
#line 2112 "inform7/Chapter 21/Equations.w"
void Data__Equations__index(void) ;
#line 159 "inform7/Chapter 21/Inform 6 Inclusions.w"
void inform_6_inclusion(parse_node *PN) ;
#line 245 "inform7/Chapter 21/Inform 6 Inclusions.w"
void Config__Inclusions__compile_inclusions_for_subject(OUTPUT_STREAM, inference_subject *infs) ;
#line 265 "inform7/Chapter 21/Inform 6 Inclusions.w"
void new_use_option(parse_node *p) ;
#line 304 "inform7/Chapter 21/Inform 6 Inclusions.w"
use_option * parse_uo(int o1, int o2) ;
#line 367 "inform7/Chapter 21/Inform 6 Inclusions.w"
void handle_set_use_option(parse_node *p) ;
#line 371 "inform7/Chapter 21/Inform 6 Inclusions.w"
void set_use_options(parse_node *p) ;
#line 449 "inform7/Chapter 21/Inform 6 Inclusions.w"
void Config__Inclusions__UseOptions__set_immediate_option_flags(int w1, int w2, use_option *uo) ;
#line 506 "inform7/Chapter 21/Inform 6 Inclusions.w"
int Config__Inclusions__get_dynamic_memory_allocation(void) ;
#line 513 "inform7/Chapter 21/Inform 6 Inclusions.w"
int Config__Inclusions__get_index_figure_thumbnails(void) ;
#line 521 "inform7/Chapter 21/Inform 6 Inclusions.w"
int uo_set_from(use_option *uo, int category, extension_file *ef) ;
#line 540 "inform7/Chapter 21/Inform 6 Inclusions.w"
void Config__Inclusions__UseOptions__compile(OUTPUT_STREAM) ;
#line 559 "inform7/Chapter 21/Inform 6 Inclusions.w"
void Config__Inclusions__compile_icl_commands(OUTPUT_STREAM) ;
#line 577 "inform7/Chapter 21/Inform 6 Inclusions.w"
void Config__Inclusions__UseOptions__index(void) ;
#line 620 "inform7/Chapter 21/Inform 6 Inclusions.w"
void index_options_in_force_from(int category, extension_file *ef) ;
#line 685 "inform7/Chapter 21/Inform 6 Inclusions.w"
void Config__Inclusions__UseOptions__TestUseOption_routine(OUTPUT_STREAM) ;
#line 35 "inform7/Chapter 21/List Together.w"
void Code__ListTogether__new(OUTPUT_STREAM, int include_articles) ;
#line 51 "inform7/Chapter 21/List Together.w"
int Code__ListTogether__compilation_coroutine(OUTPUT_STREAM) ;
#line 51 "inform7/Chapter 22/Construction Sequence.w"
void advance_phrase_time_to(int advance_to) ;
#line 75 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__traverse_for_names(void) ;
#line 145 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__traverse(void) ;
#line 176 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__register_meanings(void) ;
#line 209 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__parse_rule_parameters(void) ;
#line 228 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__add_rules_to_rulebooks(void) ;
#line 243 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__parse_rule_placements(void) ;
#line 280 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__compile_first_block(OUTPUT_STREAM) ;
#line 421 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__TimedEventsTable_array(OUTPUT_STREAM) ;
#line 426 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__TimedEventTimesTable_array(OUTPUT_STREAM) ;
#line 434 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__rulebooks_array_array(OUTPUT_STREAM) ;
#line 439 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__compile_rulebooks(OUTPUT_STREAM) ;
#line 444 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__RulebookNames_array(OUTPUT_STREAM) ;
#line 455 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__compile_rule_printing_switch(OUTPUT_STREAM) ;
#line 494 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__compile_as_needed(OUTPUT_STREAM) ;
#line 105 "inform7/Chapter 22/Phrases.w"
void Code__Phrases__create_from_preamble(parse_node *p) ;
#line 326 "inform7/Chapter 22/Phrases.w"
void parse_possible_inline_defn(int w1, int w2, int *wn, int *mor) ;
#line 336 "inform7/Chapter 22/Phrases.w"
void Code__Phrases__log(phrase *ph) ;
#line 342 "inform7/Chapter 22/Phrases.w"
void Code__Phrases__log_briefly(phrase *ph) ;
#line 349 "inform7/Chapter 22/Phrases.w"
void Code__Phrases__write_HTML_representation(OUTPUT_STREAM, phrase *ph, int format) ;
#line 356 "inform7/Chapter 22/Phrases.w"
char * Code__Routines__ToPhrases__get_inline_definition(phrase *ph) ;
#line 362 "inform7/Chapter 22/Phrases.w"
char * Code__Phrases__identifier(phrase *ph) ;
#line 366 "inform7/Chapter 22/Phrases.w"
parse_node * Code__Phrases__declaration_node(phrase *ph) ;
#line 377 "inform7/Chapter 22/Phrases.w"
void Code__Phrases__compile(OUTPUT_STREAM, phrase *ph, int *i, int max_i, stacked_variable_owner_list *legible, to_phrase_request *req, applicability_condition *acl) ;
#line 49 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__predeclare_name_in(parse_node *p) ;
#line 70 "inform7/Chapter 22/Phrase Usage.w"
rule * Code__Phrases__Usage__to_rule(ph_usage_data *phud, phrase *ph) ;
#line 235 "inform7/Chapter 22/Phrase Usage.w"
ph_usage_data Code__Phrases__Usage__new(int w1, int w2, int coarse_mode) ;
#line 476 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__get_preamble_text(ph_usage_data *phud, int *w1, int *w2) ;
#line 491 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__get_prewhile_text(ph_usage_data *phud, int *pw1, int *pw2) ;
#line 515 "inform7/Chapter 22/Phrase Usage.w"
int Code__Phrases__Usage__get_effect(ph_usage_data *phud) ;
#line 519 "inform7/Chapter 22/Phrase Usage.w"
int Code__Phrases__Usage__get_rulebook_placement(ph_usage_data *phud) ;
#line 523 "inform7/Chapter 22/Phrase Usage.w"
rulebook * Code__Phrases__Usage__get_rulebook(ph_usage_data *phud) ;
#line 527 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__set_rulebook(ph_usage_data *phud, rulebook *rb) ;
#line 532 "inform7/Chapter 22/Phrase Usage.w"
int Code__Phrases__Usage__get_timing_of_event(ph_usage_data *phud) ;
#line 536 "inform7/Chapter 22/Phrase Usage.w"
int Code__Phrases__Usage__has_name_as_constant(ph_usage_data *phud) ;
#line 543 "inform7/Chapter 22/Phrase Usage.w"
int Code__Phrases__Usage__get_equation_form(ph_usage_data *phud) ;
#line 549 "inform7/Chapter 22/Phrase Usage.w"
phrase * Code__Phrases__Usage__get_equation_inverse(ph_usage_data *phud) ;
#line 567 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__log(ph_usage_data *phud) ;
#line 615 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__log_rule_name(ph_usage_data *phud) ;
#line 626 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__write_I6_comment_describing(ph_usage_data *phud, OUTPUT_STREAM) ;
#line 635 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__index_preamble(ph_usage_data *phud) ;
#line 655 "inform7/Chapter 22/Phrase Usage.w"
ph_runtime_context_data Code__Phrases__Usage__to_runtime_context_data(ph_usage_data *phud) ;
#line 47 "inform7/Chapter 22/Phrase Runtime Context Data.w"
ph_runtime_context_data Code__Phrases__Context__new(void) ;
#line 66 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__set_always_test_actor(ph_runtime_context_data *phrcd) ;
#line 70 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__clear_always_test_actor(ph_runtime_context_data *phrcd) ;
#line 74 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__set_never_test_actor(ph_runtime_context_data *phrcd) ;
#line 78 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__set_marked_for_anyone(ph_runtime_context_data *phrcd, int to) ;
#line 82 "inform7/Chapter 22/Phrase Runtime Context Data.w"
int Code__Phrases__Context__get_marked_for_anyone(ph_runtime_context_data *phrcd) ;
#line 89 "inform7/Chapter 22/Phrase Runtime Context Data.w"
int Code__Phrases__Context__within_action_context(ph_runtime_context_data *phrcd, action_name *an) ;
#line 95 "inform7/Chapter 22/Phrase Runtime Context Data.w"
action_name * Code__Phrases__Context__required_action(ph_runtime_context_data *phrcd) ;
#line 101 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__suppress_action_testing(ph_runtime_context_data *phrcd) ;
#line 111 "inform7/Chapter 22/Phrase Runtime Context Data.w"
scene * Code__Phrases__Context__get_scene(ph_runtime_context_data *phrcd) ;
#line 124 "inform7/Chapter 22/Phrase Runtime Context Data.w"
int Code__Phrases__Context__outcome_restrictions_waived(void) ;
#line 142 "inform7/Chapter 22/Phrase Runtime Context Data.w"
int Code__Phrases__Context__compare_specificity(ph_runtime_context_data *rcd1, ph_runtime_context_data *rcd2) ;
#line 231 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__ensure_avl(rule *R) ;
#line 272 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__compile_test_head(OUTPUT_STREAM, phrase *ph, applicability_condition *acl) ;
#line 295 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__compile_test_tail(OUTPUT_STREAM, phrase *ph, applicability_condition *acl) ;
#line 159 "inform7/Chapter 22/Phrase Type Data.w"
ph_type_data Code__Phrases__TypeData__new(void) ;
#line 179 "inform7/Chapter 22/Phrase Type Data.w"
void Code__Phrases__TypeData__set_mor(ph_type_data *phtd, int mor, kind *K) ;
#line 184 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__get_mor(ph_type_data *phtd) ;
#line 188 "inform7/Chapter 22/Phrase Type Data.w"
kind * Code__Phrases__TypeData__get_return_kind(ph_type_data *phtd) ;
#line 196 "inform7/Chapter 22/Phrase Type Data.w"
char * Code__Phrases__TypeData__describe_manner_of_return(int mor, ph_type_data *phtd, kind **K) ;
#line 248 "inform7/Chapter 22/Phrase Type Data.w"
kind * Code__Phrases__TypeData__kind(ph_type_data *phtd) ;
#line 260 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__contains_variables(ph_type_data *phtd) ;
#line 270 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__tokens_contain_variable(ph_type_data *phtd, int v) ;
#line 280 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__get_no_tokens(ph_type_data *phtd) ;
#line 287 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__index_of_token_creating_a_variable(ph_type_data *phtd) ;
#line 302 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__preamble_requires_property_value(ph_type_data *phtd) ;
#line 320 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__deprecated(ph_type_data *phtd) ;
#line 324 "inform7/Chapter 22/Phrase Type Data.w"
void Code__Phrases__TypeData__deprecate_phrase(ph_type_data *phtd) ;
#line 359 "inform7/Chapter 22/Phrase Type Data.w"
void Code__Phrases__TypeData__into_stack_frame(ph_stack_frame *phsf, ph_type_data *phtd, kind *kind_in_this_compilation, int first) ;
#line 390 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__comparison(ph_type_data *phtd1, ph_type_data *phtd2) ;
#line 518 "inform7/Chapter 22/Phrase Type Data.w"
say_details new_say_details(void) ;
#line 531 "inform7/Chapter 22/Phrase Type Data.w"
void Code__Phrases__TypeData__make_sd(say_details *sd, int ro, int cs, int pos, int at, int cat) ;
#line 544 "inform7/Chapter 22/Phrase Type Data.w"
void log_say_details(say_details sd) ;
#line 563 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__is_a_say_phrase(phrase *ph) ;
#line 568 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__is_a_say_X_phrase(ph_type_data *phtd) ;
#line 575 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__is_the_primordial_say(ph_type_data *phtd) ;
#line 580 "inform7/Chapter 22/Phrase Type Data.w"
void Code__Phrases__TypeData__get_say_data(say_details *sd, int *say_cs, int *ssp_tok, int *ssp_ctok, int *ssp_pos) ;
#line 588 "inform7/Chapter 22/Phrase Type Data.w"
int preface_for_say_HTML(OUTPUT_STREAM, say_details sd, int paste_format) ;
#line 606 "inform7/Chapter 22/Phrase Type Data.w"
void epilogue_for_say_HTML(OUTPUT_STREAM, say_details sd, int paste_format) ;
#line 617 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__ssp_matches(ph_type_data *phtd, int ssp_tok, int list_pos, int *w1, int *w2) ;
#line 640 "inform7/Chapter 22/Phrase Type Data.w"
inline_details new_inline_details(void) ;
#line 659 "inform7/Chapter 22/Phrase Type Data.w"
void Code__Phrases__TypeData__make_id(inline_details *id, int op, int assgn, int let, int blk, int only_in) ;
#line 672 "inform7/Chapter 22/Phrase Type Data.w"
void log_inline_details(inline_details id) ;
#line 685 "inform7/Chapter 22/Phrase Type Data.w"
void Code__Phrases__TypeData__make_inline(ph_type_data *phtd) ;
#line 689 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__invoked_inline(phrase *ph) ;
#line 696 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__is_a_let_assignment(phrase *ph) ;
#line 701 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__is_a_let_equation(phrase *ph) ;
#line 706 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__arithmetic_operation(phrase *ph) ;
#line 710 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__is_assignment_phrase(phrase *ph) ;
#line 714 "inform7/Chapter 22/Phrase Type Data.w"
char * Code__Phrases__TypeData__only_in(phrase *ph) ;
#line 719 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__block_follows(phrase *ph) ;
#line 732 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__return_decided_dimensionally(ph_type_data *phtd) ;
#line 746 "inform7/Chapter 22/Phrase Type Data.w"
int inline_type_data_comparison(ph_type_data *phtd1, ph_type_data *phtd2) ;
#line 12 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__log(ph_type_data *phtd) ;
#line 48 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__log_briefly(ph_type_data *phtd) ;
#line 70 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__write_HTML_representation(OUTPUT_STREAM, ph_type_data *phtd, int paste_format, invocation *inv) ;
#line 178 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__inv_write_HTML_representation(OUTPUT_STREAM, invocation *inv) ;
#line 206 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__write_index_representation(ph_type_data *phtd, phrase *ph) ;
#line 231 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__write_reveal_box(ph_type_data *phtd, phrase *ph) ;
#line 314 "inform7/Chapter 22/Describing Phrase Type Data.w"
void phtd_write_I6_comment_describing(ph_type_data *phtd, OUTPUT_STREAM) ;
#line 341 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__parse(ph_type_data *phtd, int x1, int x2, int *ow1, int *ow2) ;
#line 506 "inform7/Chapter 22/Describing Phrase Type Data.w"
int phtd_parse_return_data(ph_type_data *phtd, int x1, int x2) ;
#line 535 "inform7/Chapter 22/Describing Phrase Type Data.w"
int phtd_parse_doodads(ph_type_data *phtd, int w1, int w2, int *say_flag) ;
#line 693 "inform7/Chapter 22/Describing Phrase Type Data.w"
void phtd_parse_word_sequence(ph_type_data *phtd, int w1, int w2) ;
#line 840 "inform7/Chapter 22/Describing Phrase Type Data.w"
int find_kind_variable_domains(kind *K, int *usages, kind **declarations) ;
#line 888 "inform7/Chapter 22/Describing Phrase Type Data.w"
char * Code__Phrases__TypeData__incipit(phrase *ph) ;
#line 47 "inform7/Chapter 22/Phrase Options.w"
ph_options_data Code__Phrases__Options__new(int w1, int w2) ;
#line 55 "inform7/Chapter 22/Phrase Options.w"
int Code__Phrases__Options__allows_options(ph_options_data *phod) ;
#line 66 "inform7/Chapter 22/Phrase Options.w"
int Code__Phrases__Options__parse(ph_options_data *phod, int w1, int w2) ;
#line 79 "inform7/Chapter 22/Phrase Options.w"
void Code__Phrases__Options__index(ph_options_data *phod) ;
#line 103 "inform7/Chapter 22/Phrase Options.w"
ph_options_data Code__Phrases__Options__parse_declared_options(int w1, int w2) ;
#line 155 "inform7/Chapter 22/Phrase Options.w"
void phod_add_phrase_option(ph_options_data *phod, int w1, int w2) ;
#line 195 "inform7/Chapter 22/Phrase Options.w"
int Code__Phrases__Options__parse_invoked_options(invocation *inv, int silently) ;
#line 103 "inform7/Chapter 22/Local Variables.w"
locals_slate Code__LocalVariables__blank_slate(void) ;
#line 116 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__deep_copy_locals_slate(locals_slate *slate_to, locals_slate *slate_from) ;
#line 131 "inform7/Chapter 22/Local Variables.w"
local_variable * add_to_locals_slate(locals_slate *slate, int purpose, int w1, int w2, kind *K, char *override_lvalue, int override_index) ;
#line 222 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__add_call_parameter(ph_stack_frame *phsf, int w1, int w2, kind *K) ;
#line 233 "inform7/Chapter 22/Local Variables.w"
int Code__LocalVariables__get_parameter_number(local_variable *lvar) ;
#line 243 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__new(int w1, int w2, kind *K) ;
#line 257 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__add_internal(locals_slate *slate, char *name, int purpose) ;
#line 264 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__add_internal_local(char *name) ;
#line 272 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__add_named_call(char *name) ;
#line 280 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__add_internal_local_c(char *name, char *comment) ;
#line 294 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__add_table_lookup(void) ;
#line 304 "inform7/Chapter 22/Local Variables.w"
void Code__Frames__options_parameter_is_needed(ph_stack_frame *phsf) ;
#line 314 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__deallocate(local_variable *lvar) ;
#line 325 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__deallocate_all(ph_stack_frame *phsf) ;
#line 335 "inform7/Chapter 22/Local Variables.w"
int Code__LocalVariables__count(ph_stack_frame *phsf) ;
#line 355 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__copy(ph_stack_frame *phsf_to, ph_stack_frame *phsf_from) ;
#line 379 "inform7/Chapter 22/Local Variables.w"
local_variable * find_i6_var(locals_slate *slate, char *name, int purpose) ;
#line 391 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__by_name(char *name) ;
#line 400 "inform7/Chapter 22/Local Variables.w"
int Code__LocalVariables__are_we_using_table_lookup(void) ;
#line 412 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__get_ith_parameter(int i) ;
#line 436 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__parse(ph_stack_frame *phsf, int w1, int w2) ;
#line 443 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__parse_inner(ph_stack_frame *phsf, int w1, int w2) ;
#line 481 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__monitor_local_parsing(ph_stack_frame *phsf) ;
#line 490 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__used_stack_selection(void) ;
#line 494 "inform7/Chapter 22/Local Variables.w"
int Code__LocalVariables__local_parsed_recently(ph_stack_frame *phsf) ;
#line 512 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__it_variable(void) ;
#line 522 "inform7/Chapter 22/Local Variables.w"
int Code__LocalVariables__is_possessive_form_of_it_enabled(void) ;
#line 528 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__enable_possessive_form_of_it(void) ;
#line 534 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__Pronoun__add(ph_stack_frame *phsf, int cw1, int cw2, kind *K) ;
#line 539 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__Pronoun__alias(ph_stack_frame *phsf, int ritw1, int ritw2) ;
#line 551 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__compile_storage(OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 564 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__compile_retrieval(OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 577 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__make_available_to_equation(equation *eqn) ;
#line 593 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__ensure_called_local(int w1, int w2, kind *K) ;
#line 606 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__make_necessary_callings(int w1, int w2) ;
#line 714 "inform7/Chapter 22/Local Variables.w"
int Code__LocalVariables__permit_as_new_local(specification *found, int as_calling) ;
#line 730 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__log(local_variable *lvar) ;
#line 741 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__describe_repetition_local(OUTPUT_STREAM, local_variable *lvar) ;
#line 755 "inform7/Chapter 22/Local Variables.w"
kind * Code__LocalVariables__kind(local_variable *lvar) ;
#line 760 "inform7/Chapter 22/Local Variables.w"
kind * Code__LocalVariables__unproblematic_kind(local_variable *lvar) ;
#line 769 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__set_kind(local_variable *lvar, kind *K) ;
#line 782 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__unprotect(local_variable *lvar) ;
#line 787 "inform7/Chapter 22/Local Variables.w"
int Code__LocalVariables__protected(local_variable *lvar) ;
#line 811 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__set_scope_to(local_variable *lvar, int s) ;
#line 821 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__end_scope(int s) ;
#line 841 "inform7/Chapter 22/Local Variables.w"
local_variable * Code__LocalVariables__latest_repeat_variable(void) ;
#line 872 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__begin_condition(OUTPUT_STREAM) ;
#line 877 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__add_calling_to_condition(local_variable *lvar) ;
#line 889 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__end_condition(OUTPUT_STREAM) ;
#line 916 "inform7/Chapter 22/Local Variables.w"
char * Code__LocalVariables__lvalue(local_variable *lvar) ;
#line 924 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__compile_parameter_list(OUTPUT_STREAM, ph_stack_frame *phsf, int no_vars) ;
#line 940 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__declare(OUTPUT_STREAM, ph_stack_frame *phsf, int call_pars_only) ;
#line 60 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__empty_stack(void) ;
#line 70 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__prepush_stack(void) ;
#line 77 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__push_stack(void) ;
#line 86 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__pop_stack(void) ;
#line 100 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__begin_code_blocks(void) ;
#line 112 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__end_code_blocks(void) ;
#line 139 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__beginning_block_phrase(OUTPUT_STREAM, phrase *ph) ;
#line 170 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__open_code_block(OUTPUT_STREAM, phrase *owner, kind *K, STREAM *TAIL) ;
#line 183 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__make_indentation_follow_code(OUTPUT_STREAM) ;
#line 199 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__divide_code_block(int division_form) ;
#line 206 "inform7/Chapter 22/Phrase Blocks.w"
int Code__Frames__read_division_count(int division_form) ;
#line 214 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__close_code_block(OUTPUT_STREAM) ;
#line 232 "inform7/Chapter 22/Phrase Blocks.w"
int Code__Frames__Blocks__inside_a_loop_body(void) ;
#line 245 "inform7/Chapter 22/Phrase Blocks.w"
int Code__Frames__Blocks__inside_a_conditional_block(void) ;
#line 262 "inform7/Chapter 22/Phrase Blocks.w"
int Code__Frames__Blocks__current_block_level(void) ;
#line 266 "inform7/Chapter 22/Phrase Blocks.w"
char * Code__Frames__Blocks__name_of_current_block(void) ;
#line 271 "inform7/Chapter 22/Phrase Blocks.w"
parse_node * Code__Frames__Blocks__start_of_current_block(void) ;
#line 276 "inform7/Chapter 22/Phrase Blocks.w"
kind * Code__Frames__Blocks__switch_value_kind(void) ;
#line 290 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__compile_break(OUTPUT_STREAM) ;
#line 310 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__set_variable_scope(local_variable *lvar) ;
#line 321 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__set_scope_to_block_about_to_open(local_variable *lvar) ;
#line 67 "inform7/Chapter 22/Stack Frames.w"
ph_stack_frame Code__Frames__new(void) ;
#line 87 "inform7/Chapter 22/Stack Frames.w"
ph_stack_frame * Code__Frames__new_nonphrasal(void) ;
#line 96 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__remove_nonphrase_stack_frame(void) ;
#line 105 "inform7/Chapter 22/Stack Frames.w"
ph_stack_frame * Code__Frames__boxed_frame(ph_stack_frame *phsf) ;
#line 123 "inform7/Chapter 22/Stack Frames.w"
ph_stack_frame * Code__Frames__current_stack_frame(void) ;
#line 127 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__make_current(ph_stack_frame *phsf) ;
#line 132 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__remove_current(void) ;
#line 140 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__set_kind_returned(ph_stack_frame *phsf, kind *K) ;
#line 144 "inform7/Chapter 22/Stack Frames.w"
kind * Code__Frames__get_kind_returned(void) ;
#line 153 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__set_kind_variables(ph_stack_frame *phsf, kind **vars) ;
#line 157 "inform7/Chapter 22/Stack Frames.w"
kind * Code__Frames__get_kind_variable(int N) ;
#line 164 "inform7/Chapter 22/Stack Frames.w"
kind ** Code__Frames__temporarily_set_kvs(kind **vars) ;
#line 175 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__set_stvol(ph_stack_frame *phsf, stacked_variable_owner_list *stvol) ;
#line 179 "inform7/Chapter 22/Stack Frames.w"
stacked_variable_owner_list * Code__Frames__get_stvol(void) ;
#line 190 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__determines_the_past(void) ;
#line 198 "inform7/Chapter 22/Stack Frames.w"
int Code__Frames__used_for_past_tense(void) ;
#line 208 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__log(ph_stack_frame *phsf) ;
#line 232 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__need_at_least_this_many_formals(int N) ;
#line 249 "inform7/Chapter 22/Stack Frames.w"
pointer_allocation * Code__Frames__add_allocation(kind *K, char *proto) ;
#line 269 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__compile_allocation(OUTPUT_STREAM, kind *K) ;
#line 321 "inform7/Chapter 22/Stack Frames.w"
char * Code__Frames__pall_get_local_reference(pointer_allocation *pall) ;
#line 325 "inform7/Chapter 22/Stack Frames.w"
char * Code__Frames__pall_get_expanded_schema(pointer_allocation *pall) ;
#line 347 "inform7/Chapter 22/Stack Frames.w"
STREAM * Code__Routines__begin(OUTPUT_STREAM, char *name) ;
#line 351 "inform7/Chapter 22/Stack Frames.w"
STREAM * Code__Routines__begin_numbered(OUTPUT_STREAM, char *format, int id) ;
#line 382 "inform7/Chapter 22/Stack Frames.w"
STREAM * Code__Routines__begin_framed(OUTPUT_STREAM, char *name, ph_stack_frame *phsf) ;
#line 415 "inform7/Chapter 22/Stack Frames.w"
STREAM * Code__Routines__end(OUTPUT_STREAM) ;
#line 419 "inform7/Chapter 22/Stack Frames.w"
STREAM * Code__Routines__end_retrieving(OUTPUT_STREAM, ph_stack_frame *retrieve) ;
#line 33 "inform7/Chapter 22/Parse Invocations.w"
void Code__Phrases__TypeData__register_excerpt(phrase *ph) ;
#line 66 "inform7/Chapter 22/Parse Invocations.w"
void register_phrasal(unsigned int phrase_mc, phrase *ph, int w1, int w2) ;
#line 253 "inform7/Chapter 22/Parse Invocations.w"
invocation * Code__Phrases__TypeData__parse_against(phrase *ph, meaning_list *ml) ;
#line 318 "inform7/Chapter 22/Parse Invocations.w"
void Code__Phrases__TypeData__parse_within_inv(invocation *inv) ;
#line 47 "inform7/Chapter 22/Compile Invocations.w"
void Code__Invocations__Compiler__compile(OUTPUT_STREAM, invocation_list *invl, int wn) ;
#line 104 "inform7/Chapter 22/Compile Invocations.w"
void compile_invocation_block(OUTPUT_STREAM, invocation_group *invg, int wn) ;
#line 587 "inform7/Chapter 22/Compile Invocations.w"
int compile_single_invocation(OUTPUT_STREAM, invocation *inv, source_location *where_from, tokens_packet *tokens) ;
#line 11 "inform7/Chapter 22/Compile Invocations As Calls.w"
void Code__Invocations__Compiler__csi_by_call(OUTPUT_STREAM, invocation *inv, source_location *where_from, tokens_packet *tokens) ;
#line 45 "inform7/Chapter 22/Compile Invocations As Calls.w"
void compile_function_call(OUTPUT_STREAM, tokens_packet *tokens, char *identifier, int phrase_options) ;
#line 34 "inform7/Chapter 22/Compile Invocations Inline.w"
int Code__Invocations__Compiler__csi_inline(OUTPUT_STREAM, invocation *inv, source_location *where_from, tokens_packet *tokens, int *append_close_brace) ;
#line 205 "inform7/Chapter 22/Compile Invocations Inline.w"
void Code__Invocations__Compiler__copy_and_trim(char *to, char *from) ;
#line 211 "inform7/Chapter 22/Compile Invocations Inline.w"
void Code__Invocations__Compiler__trim_tail(char *to) ;
#line 223 "inform7/Chapter 22/Compile Invocations Inline.w"
void Code__Invocations__Compiler__csi_inline_inner(OUTPUT_STREAM, char *inline_definition, invocation *inv, source_location *where_from, tokens_packet *tokens, int *append_close_brace, local_variable **my_vars) ;
#line 1618 "inform7/Chapter 22/Compile Invocations Inline.w"
specification * parse_bracing_operand_as_identifier(char *operand, phrase *ph, tokens_packet *tokens, local_variable **my_vars) ;
#line 1654 "inform7/Chapter 22/Compile Invocations Inline.w"
kind * parse_bracing_operand_as_kind(char *operand, kind_variable_declaration *kvd) ;
#line 30 "inform7/Chapter 22/Compile Phrases.w"
void Code__Routines__compile(OUTPUT_STREAM, phrase *ph, stacked_variable_owner_list *legible, to_phrase_request *req, applicability_condition *acl) ;
#line 143 "inform7/Chapter 22/Compile Phrases.w"
void Code__Routines__compile_identifier(char *identifier, phrase *ph, to_phrase_request *req) ;
#line 157 "inform7/Chapter 22/Compile Phrases.w"
void Code__Routines__ToPhrases__compile_line(OUTPUT_STREAM, int w1, int w2) ;
#line 189 "inform7/Chapter 22/Compile Phrases.w"
parse_node * Code__Routines__code_line(void) ;
#line 54 "inform7/Chapter 22/To Phrases.w"
int ph_To_compare(phrase *ph1, phrase *ph2) ;
#line 93 "inform7/Chapter 22/To Phrases.w"
void Code__Routines__ToPhrases__new(phrase *ph) ;
#line 123 "inform7/Chapter 22/To Phrases.w"
void Code__Routines__ToPhrases__register_all(void) ;
#line 133 "inform7/Chapter 22/To Phrases.w"
int Code__Routines__ToPhrases__sequence_count(phrase *ph) ;
#line 160 "inform7/Chapter 22/To Phrases.w"
to_phrase_request * Code__Routines__ToPhrases__Requests__make(phrase *ph, kind *K, kind_variable_declaration *kvd, int w1, int w2) ;
#line 211 "inform7/Chapter 22/To Phrases.w"
void Code__Routines__ToPhrases__Requests__make_identifier(char *identifier, phrase *ph, kind *req_kind) ;
#line 238 "inform7/Chapter 22/To Phrases.w"
int Code__Routines__ToPhrases__compilation_coroutine(OUTPUT_STREAM, int *i, int max_i) ;
#line 258 "inform7/Chapter 22/To Phrases.w"
void Code__Routines__ToPhrases__Requests__write_I6_comment_describing( to_phrase_request *req, OUTPUT_STREAM) ;
#line 272 "inform7/Chapter 22/To Phrases.w"
kind * Code__Routines__ToPhrases__Requests__kind(to_phrase_request *req) ;
#line 277 "inform7/Chapter 22/To Phrases.w"
kind ** Code__Routines__ToPhrases__Requests__kind_variables(to_phrase_request *req) ;
#line 287 "inform7/Chapter 22/To Phrases.w"
int Code__Routines__ToPhrases__allows_options(phrase *ph) ;
#line 291 "inform7/Chapter 22/To Phrases.w"
int Code__Routines__ToPhrases__parse_phrase_option_used(phrase *ph, int w1, int w2) ;
#line 38 "inform7/Chapter 22/Say Phrases.w"
int Code__Invocations__Compiler__verify(invocation_list *invl) ;
#line 290 "inform7/Chapter 22/Say Phrases.w"
void Code__Phrases__add_say_construction_to_error(int ssp_tok) ;
#line 300 "inform7/Chapter 22/Say Phrases.w"
void add_scte_list(int ssp_tok, int list_pos) ;
#line 323 "inform7/Chapter 22/Say Phrases.w"
void Code__SayPhrases__compile_invocation_group(OUTPUT_STREAM, invocation_group *invg, int stage) ;
#line 33 "inform7/Chapter 22/Phrases as Values.w"
constant_phrase * Code__Phrases__Constants__create(int n1, int n2, int r1, int r2) ;
#line 47 "inform7/Chapter 22/Phrases as Values.w"
constant_phrase * Code__Phrases__Constants__parse(int n1, int n2) ;
#line 65 "inform7/Chapter 22/Phrases as Values.w"
kind * Code__Phrases__Constants__kind(constant_phrase *cphr) ;
#line 81 "inform7/Chapter 22/Phrases as Values.w"
phrase * Code__Phrases__Constants__as_phrase(constant_phrase *cphr) ;
#line 100 "inform7/Chapter 22/Phrases as Values.w"
void Code__Phrases__Constants__compile(OUTPUT_STREAM, constant_phrase *cphr) ;
#line 111 "inform7/Chapter 22/Phrases as Values.w"
void Code__Phrases__Constants__compile_closures(OUTPUT_STREAM) ;
#line 160 "inform7/Chapter 22/Phrases as Values.w"
void Code__Phrases__Constants__compile_default_closure(OUTPUT_STREAM, char *closure_identifier, kind *K) ;
#line 27 "inform7/Chapter 22/Phrasebook Index.w"
void Code__Phrases__index_page_Phrasebook(void) ;
#line 198 "inform7/Chapter 22/Phrasebook Index.w"
int ph_same_doc(phrase *p1, phrase *p2) ;
#line 211 "inform7/Chapter 22/Phrasebook Index.w"
void Code__Phrases__index_definition_area(int x1, int x2, int show_if_unhyphenated) ;
#line 107 "inform7/Chapter 22/Adjectival Definitions.w"
void Code__Phrases__Adjectives__traverse(void) ;
#line 196 "inform7/Chapter 22/Adjectival Definitions.w"
definition * def_new(parse_node *q) ;
#line 206 "inform7/Chapter 22/Adjectival Definitions.w"
adjective_meaning * Code__Phrases__Adjectives__Condition__parse(parse_node *q, int sense, int adj_name_w1, int adj_name_w2, int dom_name_w1, int dom_name_w2, int cond_w1, int cond_w2, int called_w1, int called_w2) ;
#line 227 "inform7/Chapter 22/Adjectival Definitions.w"
void Code__Phrases__Adjectives__Condition__compiling_soon(adjective_meaning *am, definition *def, int T) ;
#line 231 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__Condition__compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 272 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__Condition__assert(definition *def, inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) ;
#line 278 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__Condition__index(definition *def) ;
#line 286 "inform7/Chapter 22/Adjectival Definitions.w"
void Code__Phrases__Adjectives__define_by_phrase(parse_node *p, phrase *ph, int *cw1, int *cw2, kind **K) ;
#line 304 "inform7/Chapter 22/Adjectival Definitions.w"
adjective_meaning * Code__Phrases__Adjectives__Phrasal__parse(parse_node *q, int sense, int adj_name_w1, int adj_name_w2, int dom_name_w1, int dom_name_w2, int cond_w1, int cond_w2, int called_w1, int called_w2) ;
#line 322 "inform7/Chapter 22/Adjectival Definitions.w"
void Code__Phrases__Adjectives__Phrasal__compiling_soon(adjective_meaning *am, definition *def, int T) ;
#line 325 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__Phrasal__compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 329 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__Phrasal__assert(definition *def, inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) ;
#line 334 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__Phrasal__index(definition *def) ;
#line 350 "inform7/Chapter 22/Adjectival Definitions.w"
adjective_meaning * Code__Phrases__Adjectives__RawPhrasal__parse(parse_node *q, int sense, int adj_name_w1, int adj_name_w2, int dom_name_w1, int dom_name_w2, int cond_w1, int cond_w2, int called_w1, int called_w2) ;
#line 389 "inform7/Chapter 22/Adjectival Definitions.w"
void Code__Phrases__Adjectives__RawPhrasal__compiling_soon(adjective_meaning *am, definition *def, int T) ;
#line 392 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__RawPhrasal__compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 396 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__RawPhrasal__assert(definition *def, inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) ;
#line 401 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__RawPhrasal__index(definition *def) ;
#line 415 "inform7/Chapter 22/Adjectival Definitions.w"
adjective_meaning * Code__Phrases__Adjectives__RawCondition__parse(parse_node *q, int sense, int adj_name_w1, int adj_name_w2, int dom_name_w1, int dom_name_w2, int cond_w1, int cond_w2, int called_w1, int called_w2) ;
#line 442 "inform7/Chapter 22/Adjectival Definitions.w"
void Code__Phrases__Adjectives__RawCondition__compiling_soon(adjective_meaning *am, definition *def, int T) ;
#line 445 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__RawCondition__compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 449 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__RawCondition__assert(definition *def, inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) ;
#line 454 "inform7/Chapter 22/Adjectival Definitions.w"
int Code__Phrases__Adjectives__RawCondition__index(definition *def) ;
#line 37 "inform7/Chapter 22/Timed Phrases.w"
void Code__Phrases__Timed__TimedEventsTable_array(OUTPUT_STREAM) ;
#line 51 "inform7/Chapter 22/Timed Phrases.w"
void Code__Phrases__Timed__TimedEventTimesTable_array(OUTPUT_STREAM) ;
#line 68 "inform7/Chapter 22/Timed Phrases.w"
void Code__Phrases__Timed__note_usage(phrase *ph, parse_node *at) ;
#line 87 "inform7/Chapter 22/Timed Phrases.w"
void Code__Phrases__Timed__check_for_unused(void) ;
#line 105 "inform7/Chapter 22/Timed Phrases.w"
void Code__Phrases__Timed__index(void) ;
#line 110 "inform7/Chapter 23/Rules.w"
rule * Code__Rules__new(int w1, int w2, int named) ;
#line 154 "inform7/Chapter 23/Rules.w"
rule * Code__Rules__by_name(int w1, int w2) ;
#line 178 "inform7/Chapter 23/Rules.w"
void Code__Rules__vet_name(int w1, int w2) ;
#line 197 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_I7_definition(rule *R, phrase *ph) ;
#line 201 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_I6_definition(rule *R, char *identifier) ;
#line 205 "inform7/Chapter 23/Rules.w"
char * Code__Rules__get_I6_definition(rule *R) ;
#line 209 "inform7/Chapter 23/Rules.w"
phrase * Code__Rules__get_I7_definition(rule *R) ;
#line 217 "inform7/Chapter 23/Rules.w"
void Code__Rules__impose_constraint(rule *S, rule *R, int w1, int w2, int sense) ;
#line 247 "inform7/Chapter 23/Rules.w"
void Code__Rules__compile_constraint(OUTPUT_STREAM, applicability_condition *acl) ;
#line 291 "inform7/Chapter 23/Rules.w"
void Code__Rules__log(rule *R) ;
#line 306 "inform7/Chapter 23/Rules.w"
int Code__Rules__compare_specificity(rule *R1, rule *R2, int dflag) ;
#line 330 "inform7/Chapter 23/Rules.w"
int Code__Rules__eq(rule *R1, rule *R2) ;
#line 350 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_kind_from(rule *R, rulebook *RB) ;
#line 379 "inform7/Chapter 23/Rules.w"
specification * Code__Rules__to_specification(rule *R) ;
#line 387 "inform7/Chapter 23/Rules.w"
rule * Code__Rules__from_specification(specification *spec) ;
#line 396 "inform7/Chapter 23/Rules.w"
void Code__Rules__acquire_stvol(rule *R, stacked_variable_owner_list *stvol) ;
#line 401 "inform7/Chapter 23/Rules.w"
void Code__Rules__acquire_action_variables(rule *R) ;
#line 425 "inform7/Chapter 23/Rules.w"
void Code__Rules__request_automatic_placement(rule *R) ;
#line 437 "inform7/Chapter 23/Rules.w"
void Code__Rules__compile(OUTPUT_STREAM, rule *R) ;
#line 451 "inform7/Chapter 23/Rules.w"
void Code__Rules__compile_rule_printing_switch(OUTPUT_STREAM) ;
#line 483 "inform7/Chapter 23/Rules.w"
void Code__Rules__compile_comment(OUTPUT_STREAM, rule *R, int index, int from) ;
#line 497 "inform7/Chapter 23/Rules.w"
void Code__Rules__compile_definition(OUTPUT_STREAM, rule *R, int *i, int max_i) ;
#line 534 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_italicised_index_text(rule *R, int w1, int w2) ;
#line 544 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_numbered_rules(void) ;
#line 551 "inform7/Chapter 23/Rules.w"
int Code__Rules__index(rule *R, rulebook *owner, scene *during_scene) ;
#line 678 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_always_test_actor(rule *R) ;
#line 685 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_never_test_actor(rule *R) ;
#line 692 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_marked_for_anyone(rule *R, int to) ;
#line 699 "inform7/Chapter 23/Rules.w"
void Code__Rules__suppress_action_testing(rule *R) ;
#line 706 "inform7/Chapter 23/Rules.w"
void Code__Rules__copy_actor_test_flags(rule *R_to, rule *R_from) ;
#line 724 "inform7/Chapter 23/Rules.w"
int Code__Rules__rule_is_named(rule *R) ;
#line 729 "inform7/Chapter 23/Rules.w"
response_message * Code__Rules__rule_defines_response(rule *R, int code) ;
#line 735 "inform7/Chapter 23/Rules.w"
void Code__Rules__check_response_usages(void) ;
#line 766 "inform7/Chapter 23/Rules.w"
void Code__Rules__now_rule_defines_response(rule *R, int code, response_message *resp) ;
#line 772 "inform7/Chapter 23/Rules.w"
void Code__Rules__now_rule_needs_response(rule *R, int code, int wn) ;
#line 778 "inform7/Chapter 23/Rules.w"
int Code__Rules__get_response_wn(rule *R, int code) ;
#line 783 "inform7/Chapter 23/Rules.w"
parse_node * Code__Rules__get_response_sentence(rule *R, int code) ;
#line 788 "inform7/Chapter 23/Rules.w"
ph_stack_frame * Code__Rules__stack_frame(rule *R) ;
#line 51 "inform7/Chapter 23/Rule Bookings.w"
booking * Code__Rules__Bookings__new(rule *R) ;
#line 68 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__log(booking *br) ;
#line 83 "inform7/Chapter 23/Rule Bookings.w"
rule * Code__Rules__Bookings__get_rule(booking *br) ;
#line 103 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__request_automatic_placement(booking *br) ;
#line 113 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__make_automatic_placements(void) ;
#line 133 "inform7/Chapter 23/Rule Bookings.w"
void Code__Phrases__Usage__place_in_rulebook(ph_usage_data *phud, booking *br) ;
#line 212 "inform7/Chapter 23/Rule Bookings.w"
int compare_specificity_of_br(booking *br1, booking *br2, int log) ;
#line 247 "inform7/Chapter 23/Rule Bookings.w"
booking * Code__Rules__Bookings__list_new(void) ;
#line 305 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_add(booking *list_head, booking *new_rule, int placing, int side, rule *ref_rule) ;
#line 472 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_remove(booking *list_head, rule *ref_rule) ;
#line 485 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_log(booking *list_head) ;
#line 499 "inform7/Chapter 23/Rule Bookings.w"
int Code__Rules__Bookings__no_rules_in_list(booking *list_head) ;
#line 508 "inform7/Chapter 23/Rule Bookings.w"
int Code__Rules__Bookings__list_is_empty(booking *list_head, scene *S) ;
#line 521 "inform7/Chapter 23/Rule Bookings.w"
int Code__Rules__Bookings__list_is_empty_of_i7_rules(booking *list_head) ;
#line 530 "inform7/Chapter 23/Rule Bookings.w"
int Code__Rules__Bookings__list_contains(booking *list_head, rule *to_find) ;
#line 539 "inform7/Chapter 23/Rule Bookings.w"
int Code__Rules__Bookings__list_contains_ph(booking *list_head, phrase *ph_to_find) ;
#line 554 "inform7/Chapter 23/Rule Bookings.w"
int Code__Rules__Bookings__list_index(booking *list_head, scene *context, action_name *action_context, char *billing, rulebook *owner, int *resp_count) ;
#line 583 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_suppress_indexed_links(void) ;
#line 587 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_resume_indexed_links(void) ;
#line 591 "inform7/Chapter 23/Rule Bookings.w"
void br_start_index_line(booking *prev, char *billing) ;
#line 602 "inform7/Chapter 23/Rule Bookings.w"
void br_show_linkage_icon(booking *prev) ;
#line 624 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_judge_ordering(booking *list_head) ;
#line 720 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_compile_rule_phrases(booking *list_head, OUTPUT_STREAM, int *i, int max_i) ;
#line 757 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__start_list_compilation(OUTPUT_STREAM) ;
#line 777 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_compile(booking *list_head, OUTPUT_STREAM, char *identifier, int action_based, int parameter_based) ;
#line 931 "inform7/Chapter 23/Rule Bookings.w"
action_name * br_required_action(booking *br) ;
#line 222 "inform7/Chapter 23/Rulebooks.w"
rulebook * Code__Rulebooks__new(kind *create_as, int w1, int w2) ;
#line 275 "inform7/Chapter 23/Rulebooks.w"
outcomes * Code__Rulebooks__get_outcomes(rulebook *rb) ;
#line 279 "inform7/Chapter 23/Rulebooks.w"
specification * Code__Rulebooks__to_specification(rulebook *rb) ;
#line 287 "inform7/Chapter 23/Rulebooks.w"
kind * Code__Rulebooks__content_kind(rulebook *rb) ;
#line 293 "inform7/Chapter 23/Rulebooks.w"
rulebook * Code__Rulebooks__from_specification(specification *spec) ;
#line 303 "inform7/Chapter 23/Rulebooks.w"
rulebook * Code__Rulebooks__new_automatic(int w1, int w2, kind *basis, int oc, int ata, int ubfaa, int rda) ;
#line 316 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__set_alt_name(rulebook *rb, int aw1, int aw2) ;
#line 322 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__fragment_by_actions(rulebook *rb, int wn) ;
#line 326 "inform7/Chapter 23/Rulebooks.w"
int Code__Rulebooks__requires_specific_action(rulebook *rb) ;
#line 338 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__affected_by_placement(rulebook *rb, parse_node *where) ;
#line 345 "inform7/Chapter 23/Rulebooks.w"
int rb_no_placements(rulebook *rb) ;
#line 352 "inform7/Chapter 23/Rulebooks.w"
void rb_index_placements(rulebook *rb) ;
#line 367 "inform7/Chapter 23/Rulebooks.w"
int Code__Rulebooks__focus(rulebook *rb) ;
#line 371 "inform7/Chapter 23/Rulebooks.w"
kind * Code__Rulebooks__get_parameter_kind(rulebook *rb) ;
#line 375 "inform7/Chapter 23/Rulebooks.w"
int Code__Rulebooks__used_by_future_actions(rulebook *rb) ;
#line 379 "inform7/Chapter 23/Rulebooks.w"
int Code__Rulebooks__is_empty(rulebook *rb, scene *context) ;
#line 384 "inform7/Chapter 23/Rulebooks.w"
int Code__Rulebooks__no_rules(rulebook *rb) ;
#line 389 "inform7/Chapter 23/Rulebooks.w"
int Code__Rulebooks__rule_in_rulebook(rule *R, rulebook *rb) ;
#line 394 "inform7/Chapter 23/Rulebooks.w"
booking * Code__Rulebooks__first_booking(rulebook *rb) ;
#line 399 "inform7/Chapter 23/Rulebooks.w"
int Code__Rulebooks__runs_during_activities(rulebook *rb) ;
#line 429 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__add_variable(rulebook *rb, parse_node *cnode) ;
#line 508 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__make_stvs_accessible(rulebook *rb, stacked_variable_owner *stvo) ;
#line 512 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__rulebook_var_creators_array(OUTPUT_STREAM) ;
#line 529 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__rulebook_var_creators_lookup(OUTPUT_STREAM) ;
#line 545 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__log_name_only(rulebook *rb) ;
#line 549 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__log(rulebook *rb) ;
#line 555 "inform7/Chapter 23/Rulebooks.w"
int Code__Rulebooks__index(rulebook *rb, char *billing, scene *context, action_name *action_context, int *resp_count) ;
#line 571 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__index_action_rules(action_name *an, rulebook *rb, int code, char *desc, int *resp_count) ;
#line 641 "inform7/Chapter 23/Rulebooks.w"
rulebook_match rb_match_from_description(int w1, int w2) ;
#line 731 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__attach_rule(rulebook *rb, booking *the_new_rule, int placing, int side, rule *ref_rule) ;
#line 791 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__detach_rule(rulebook *rb, rule *the_new_rule) ;
#line 801 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__compile_rule_phrases(rulebook *rb, OUTPUT_STREAM, int *i, int max_i) ;
#line 814 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__rulebooks_array_array(OUTPUT_STREAM) ;
#line 822 "inform7/Chapter 23/Rulebooks.w"
int Code__Rulebooks__procedurals_exist(void) ;
#line 826 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__compile_rulebooks(OUTPUT_STREAM) ;
#line 841 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__RulebookNames_array(OUTPUT_STREAM) ;
#line 881 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__parse_properties(rulebook *rb, int w1, int w2) ;
#line 886 "inform7/Chapter 23/Rulebooks.w"
kind * Code__Rulebooks__kind_from_context(void) ;
#line 901 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__index_page(int n) ;
#line 1111 "inform7/Chapter 23/Rulebooks.w"
int noteworthy_rulebooks(extension_file *ef) ;
#line 1129 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__index_scene(void) ;
#line 1135 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__index_rules_box(char *name, int w1, int w2, char *doc_link, rulebook *rb, activity *av, char *text, int indent, int hide_behind_plus) ;
#line 90 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__initialise_outcomes(outcomes *outs, kind *K, int def) ;
#line 97 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__set_default_outcome(outcomes *outs, int def) ;
#line 101 "inform7/Chapter 23/Focus and Outcome.w"
kind * Code__Rulebooks__get_outcome_kind(outcomes *outs) ;
#line 230 "inform7/Chapter 23/Focus and Outcome.w"
named_rulebook_outcome * rbno_by_name(int w1, int w2) ;
#line 245 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__compile_default_outcome(outcomes *outs, OUTPUT_STREAM) ;
#line 270 "inform7/Chapter 23/Focus and Outcome.w"
rulebook_outcome * rbo_from_context(named_rulebook_outcome *rbno) ;
#line 287 "inform7/Chapter 23/Focus and Outcome.w"
rulebook * Code__Rulebooks__allow_outcome(named_rulebook_outcome *rbno) ;
#line 306 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__compile_outcome(OUTPUT_STREAM, named_rulebook_outcome *rbno) ;
#line 341 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__index_outcomes(outcomes *outs, int suppress_outcome) ;
#line 374 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__RulebookOutcomePrintingRule_routine(OUTPUT_STREAM) ;
#line 391 "inform7/Chapter 23/Focus and Outcome.w"
char * Code__Rulebooks__get_default_value(void) ;
#line 403 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__initialise_focus(focus *foc, kind *parameter_kind) ;
#line 416 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__modify_rule_to_suit_focus(focus *foc, rule *R) ;
#line 430 "inform7/Chapter 23/Focus and Outcome.w"
int Code__Rulebooks__get_focus(focus *foc) ;
#line 434 "inform7/Chapter 23/Focus and Outcome.w"
kind * Code__Rulebooks__get_focus_parameter_kind(focus *foc) ;
#line 438 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__set_focus_ata(focus *foc, int ata) ;
#line 17 "inform7/Chapter 23/Rule Placement Sentences.w"
void Code__Rules__declare_I6_written_rule(int w1, int w2, parse_node *p2) ;
#line 85 "inform7/Chapter 23/Rule Placement Sentences.w"
void Code__Rules__request_substitute(parse_node *p1, parse_node *p2, parse_node *p3, int sense) ;
#line 115 "inform7/Chapter 23/Rule Placement Sentences.w"
void Code__Rules__constrain_effect(parse_node *p1, parse_node *p2, int sense) ;
#line 217 "inform7/Chapter 23/Rule Placement Sentences.w"
void Code__Rules__manual_placement(int verb, parse_node *subj) ;
#line 249 "inform7/Chapter 23/Rule Placement Sentences.w"
void Code__Rules__place_in_rulebook(parse_node *p1, parse_node *p2, int sense) ;
#line 55 "inform7/Chapter 23/Stacked Variables.w"
void stv_compile_lvalue_to_text(stacked_variable *stv, char *to) ;
#line 62 "inform7/Chapter 23/Stacked Variables.w"
void Code__StackedVariables__compile_rvalue_to_text(stacked_variable *stv, char *to) ;
#line 69 "inform7/Chapter 23/Stacked Variables.w"
int Code__StackedVariables__get_owner_id(stacked_variable *stv) ;
#line 73 "inform7/Chapter 23/Stacked Variables.w"
int Code__StackedVariables__get_offset(stacked_variable *stv) ;
#line 77 "inform7/Chapter 23/Stacked Variables.w"
kind * Code__StackedVariables__get_kind(stacked_variable *stv) ;
#line 82 "inform7/Chapter 23/Stacked Variables.w"
nonlocal_variable * Code__StackedVariables__get_variable(stacked_variable *stv) ;
#line 87 "inform7/Chapter 23/Stacked Variables.w"
void Code__StackedVariables__set_matching_text(stacked_variable *stv, int w1, int w2) ;
#line 91 "inform7/Chapter 23/Stacked Variables.w"
void stv_get_matching_text(stacked_variable *stv, int *w1, int *w2) ;
#line 95 "inform7/Chapter 23/Stacked Variables.w"
stacked_variable * Code__StackedVariables__Owners__parse_match_clause(stacked_variable_owner *stvo, int w1, int w2) ;
#line 107 "inform7/Chapter 23/Stacked Variables.w"
stacked_variable_owner * Code__StackedVariables__Owners__new(int id) ;
#line 115 "inform7/Chapter 23/Stacked Variables.w"
int Code__StackedVariables__Owners__empty(stacked_variable_owner *stvo) ;
#line 120 "inform7/Chapter 23/Stacked Variables.w"
stacked_variable * Code__StackedVariables__Owners__add(stacked_variable_owner *stvo, int w1, int w2, kind *K) ;
#line 144 "inform7/Chapter 23/Stacked Variables.w"
stacked_variable_owner_list * Code__StackedVariables__Owners__Lists__add_owner(stacked_variable_owner_list *stvol, stacked_variable_owner *stvo) ;
#line 163 "inform7/Chapter 23/Stacked Variables.w"
stacked_variable_owner_list * Code__StackedVariables__Owners__Lists__append(stacked_variable_owner_list *stvol, stacked_variable_owner_list *extras) ;
#line 173 "inform7/Chapter 23/Stacked Variables.w"
int stvl_length(stacked_variable_list *stvl) ;
#line 182 "inform7/Chapter 23/Stacked Variables.w"
void Code__StackedVariables__Owners__index(stacked_variable_owner *stvo) ;
#line 192 "inform7/Chapter 23/Stacked Variables.w"
stacked_variable * Code__StackedVariables__Owners__Lists__parse(stacked_variable_owner_list *stvol, int w1, int w2) ;
#line 204 "inform7/Chapter 23/Stacked Variables.w"
stacked_variable * stvl_parse(stacked_variable_list *stvl, int w1, int w2) ;
#line 213 "inform7/Chapter 23/Stacked Variables.w"
stacked_variable_list * stvl_add_to_list(stacked_variable_list *stvl, stacked_variable *stv) ;
#line 224 "inform7/Chapter 23/Stacked Variables.w"
int Code__StackedVariables__Owners__compile_frame_creator(OUTPUT_STREAM, stacked_variable_owner *stvo, char *name_prototype, int name_id) ;
#line 68 "inform7/Chapter 24/Chronology.w"
time_period Code__Chronology__TimePeriods__new(void) ;
#line 79 "inform7/Chapter 24/Chronology.w"
time_period Code__Chronology__TimePeriods__new_tense_marker(int t) ;
#line 85 "inform7/Chapter 24/Chronology.w"
time_period * Code__Chronology__TimePeriods__store(time_period tp) ;
#line 91 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__log_tense_number(int t) ;
#line 101 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__TimePeriods__log(time_period *tp) ;
#line 117 "inform7/Chapter 24/Chronology.w"
int Code__Chronology__TimePeriods__is_valid(time_period *tp) ;
#line 120 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__TimePeriods__make_invalid(time_period *tp) ;
#line 124 "inform7/Chapter 24/Chronology.w"
int Code__Chronology__TimePeriods__get_tense(time_period *tp) ;
#line 128 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__TimePeriods__set_tense(time_period *tp, int t) ;
#line 132 "inform7/Chapter 24/Chronology.w"
int tp_duration_count(time_period *tp) ;
#line 148 "inform7/Chapter 24/Chronology.w"
int Code__Chronology__TimePeriods__compare_specificity(time_period *tp1, time_period *tp2) ;
#line 230 "inform7/Chapter 24/Chronology.w"
time_period Code__Chronology__TimePeriods__parse(int w1, int w2) ;
#line 264 "inform7/Chapter 24/Chronology.w"
void ap_compile_forced_to_present(OUTPUT_STREAM, action_pattern ap) ;
#line 272 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__compile_past_action_pattern(OUTPUT_STREAM, time_period duration, action_pattern ap) ;
#line 318 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__compile_past_tense_condition(OUTPUT_STREAM, time_period duration, specification *spec) ;
#line 405 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__allow_no_further_past_tenses(void) ;
#line 435 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__past_actions_i6_routines(OUTPUT_STREAM) ;
#line 478 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__past_tenses_i6_escape(OUTPUT_STREAM) ;
#line 585 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__chronology_extents_i6_escape(OUTPUT_STREAM) ;
#line 107 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__start(void) ;
#line 119 "inform7/Chapter 24/Actions.w"
int actions_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) ;
#line 135 "inform7/Chapter 24/Actions.w"
int actions_compile_constant(OUTPUT_STREAM, kind *K, specification *spec) ;
#line 156 "inform7/Chapter 24/Actions.w"
int actions_offered_property(kind *K, specification *owner, parse_node *what) ;
#line 166 "inform7/Chapter 24/Actions.w"
int actions_offered_specification(specification *owner, int w1, int w2) ;
#line 179 "inform7/Chapter 24/Actions.w"
int actions_typecheck_equality(kind *K1, kind *K2) ;
#line 193 "inform7/Chapter 24/Actions.w"
int actions_forbid_setting(kind *K) ;
#line 209 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__coerce_TEST_ACTION_to_STORED_ACTION(specification *spec) ;
#line 227 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__coerce_TEST_ACTION_to_DESCRIPTION_OF_ACTION(specification *spec) ;
#line 258 "inform7/Chapter 24/Actions.w"
action_name * act_new(int w1, int w2, int implemented_by_I7) ;
#line 359 "inform7/Chapter 24/Actions.w"
int action_names_overlap(action_name *an1, action_name *an2) ;
#line 370 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__log(action_name *an) ;
#line 414 "inform7/Chapter 24/Actions.w"
action_name * Plugins__Actions__longest_null(int w1, int w2, int tense, int *excess) ;
#line 430 "inform7/Chapter 24/Actions.w"
int Plugins__Actions__it_optional(action_name *an) ;
#line 434 "inform7/Chapter 24/Actions.w"
int Plugins__Actions__abbreviable(action_name *an) ;
#line 438 "inform7/Chapter 24/Actions.w"
char * Plugins__Actions__identifier(action_name *an) ;
#line 442 "inform7/Chapter 24/Actions.w"
rulebook * Plugins__Actions__get_fragmented_rulebook(action_name *an, rulebook *rb) ;
#line 449 "inform7/Chapter 24/Actions.w"
rulebook * Plugins__Actions__switch_fragmented_rulebook(action_name *new_an, rulebook *orig) ;
#line 460 "inform7/Chapter 24/Actions.w"
void actions_set_specification_text(action_name *an, int wn) ;
#line 463 "inform7/Chapter 24/Actions.w"
int an_get_specification_text(action_name *an) ;
#line 472 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__name_all(void) ;
#line 480 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__translates(int w1, int w2, parse_node *p2) ;
#line 501 "inform7/Chapter 24/Actions.w"
int Plugins__Actions__get_stem_length(action_name *an) ;
#line 564 "inform7/Chapter 24/Actions.w"
void an_add_variable(action_name *an, parse_node *cnode) ;
#line 689 "inform7/Chapter 24/Actions.w"
stacked_variable * Plugins__Actions__parse_match_clause(action_name *an, int w1, int w2) ;
#line 693 "inform7/Chapter 24/Actions.w"
void compile_action_name_var_creators(OUTPUT_STREAM) ;
#line 867 "inform7/Chapter 24/Actions.w"
void act_parse_definition(parse_node *p) ;
#line 902 "inform7/Chapter 24/Actions.w"
int Plugins__Actions__is_out_of_world(action_name *an) ;
#line 907 "inform7/Chapter 24/Actions.w"
kind * Plugins__Actions__get_data_type_of_noun(action_name *an) ;
#line 911 "inform7/Chapter 24/Actions.w"
kind * Plugins__Actions__get_data_type_of_second_noun(action_name *an) ;
#line 915 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__set_text_to_name_tensed(action_name *an, int *x1, int *x2, int tense) ;
#line 925 "inform7/Chapter 24/Actions.w"
int Plugins__Actions__can_have_parameters(action_name *an) ;
#line 930 "inform7/Chapter 24/Actions.w"
int Plugins__Actions__get_max_parameters(action_name *an) ;
#line 942 "inform7/Chapter 24/Actions.w"
int Plugins__Actions__can_be_compiled_in_past_tense(action_name *an) ;
#line 951 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__compile_action_bitmap_property(OUTPUT_STREAM) ;
#line 956 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__ActionHappened_array(OUTPUT_STREAM) ;
#line 968 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__add_gl(action_name *an, grammar_line *gl) ;
#line 973 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__remove_gl(action_name *an) ;
#line 980 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__check_types_for_grammar(action_name *an, int tok_values, kind **tok_value_kinds) ;
#line 1095 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__compile_action_routines(OUTPUT_STREAM) ;
#line 1114 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__ActionData_array(OUTPUT_STREAM) ;
#line 1155 "inform7/Chapter 24/Actions.w"
void DB_Action_Details(OUTPUT_STREAM) ;
#line 1204 "inform7/Chapter 24/Actions.w"
void cat_something2(OUTPUT_STREAM, action_name *an, int n) ;
#line 1214 "inform7/Chapter 24/Actions.w"
void print_action_text_to(int w1, int w2, int start, OUTPUT_STREAM) ;
#line 1224 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__ActionCoding_array(OUTPUT_STREAM) ;
#line 1240 "inform7/Chapter 24/Actions.w"
int Plugins__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 1361 "inform7/Chapter 24/Actions.w"
void act_index_something(action_name *an, int argc) ;
#line 38 "inform7/Chapter 24/Action Name Lists.w"
action_name_list * anl_new(void) ;
#line 53 "inform7/Chapter 24/Action Name Lists.w"
void Plugins__Actions__Lists__log(action_name_list *anl) ;
#line 69 "inform7/Chapter 24/Action Name Lists.w"
void Plugins__Actions__Lists__log_briefly(action_name_list *anl) ;
#line 85 "inform7/Chapter 24/Action Name Lists.w"
action_name * Plugins__Actions__Lists__get_singleton_action(action_name_list *anl) ;
#line 235 "inform7/Chapter 24/Action Name Lists.w"
action_name_list * flip_anl_parity(action_name_list *anl, int flip_all) ;
#line 251 "inform7/Chapter 24/Action Name Lists.w"
action_name_list * Plugins__Actions__Lists__parse(int w1, int w2, int tense) ;
#line 263 "inform7/Chapter 24/Action Name Lists.w"
action_name_list * anl_parse_internal(int w1, int w2) ;
#line 355 "inform7/Chapter 24/Action Name Lists.w"
action_name_list * Plugins__Actions__Lists__extract_actions_only(int w1, int w2) ;
#line 373 "inform7/Chapter 24/Action Name Lists.w"
action_name * Plugins__Actions__Lists__get_single_action(action_name_list *anl) ;
#line 400 "inform7/Chapter 24/Action Name Lists.w"
int Plugins__Actions__Lists__get_explicit_anyone_flag(action_name_list *anl) ;
#line 405 "inform7/Chapter 24/Action Name Lists.w"
int Plugins__Actions__Lists__negated(action_name_list *anl) ;
#line 410 "inform7/Chapter 24/Action Name Lists.w"
void Plugins__Actions__Lists__compile(OUTPUT_STREAM, action_name_list *anl) ;
#line 432 "inform7/Chapter 24/Action Name Lists.w"
int Plugins__Actions__Lists__compare_specificity(action_name_list *anl1, action_name_list *anl2) ;
#line 444 "inform7/Chapter 24/Action Name Lists.w"
int count_actions_covered(action_name_list *anl) ;
#line 127 "inform7/Chapter 24/Action Patterns.w"
action_pattern Plugins__Actions__Patterns__new(void) ;
#line 158 "inform7/Chapter 24/Action Patterns.w"
ap_optional_clause * apoc_new(stacked_variable *stv, specification *spec) ;
#line 167 "inform7/Chapter 24/Action Patterns.w"
void ap_add_optional_clause(action_pattern *ap, ap_optional_clause *apoc) ;
#line 210 "inform7/Chapter 24/Action Patterns.w"
int ap_count_optional_clauses(action_pattern *ap) ;
#line 221 "inform7/Chapter 24/Action Patterns.w"
int compare_specificity_of_apoc_list(action_pattern *ap1, action_pattern *ap2) ;
#line 248 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__log(action_pattern *ap) ;
#line 276 "inform7/Chapter 24/Action Patterns.w"
action_pattern * ap_store(action_pattern ap) ;
#line 282 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__is_named(action_pattern *ap) ;
#line 288 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__is_valid(action_pattern *ap) ;
#line 293 "inform7/Chapter 24/Action Patterns.w"
int ap_is_substantial(action_pattern *ap) ;
#line 298 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__is_request(action_pattern *ap) ;
#line 303 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__within_action_context(action_pattern *ap, action_name *an) ;
#line 315 "inform7/Chapter 24/Action Patterns.w"
action_name_list * Plugins__Actions__Patterns__list(action_pattern *ap) ;
#line 320 "inform7/Chapter 24/Action Patterns.w"
action_name * Plugins__Actions__Patterns__required_action(action_pattern *ap) ;
#line 326 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__object_based(action_pattern *ap) ;
#line 331 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__is_unspecific(action_pattern *ap) ;
#line 339 "inform7/Chapter 24/Action Patterns.w"
int ap_clause_is_unspecific(specification *spec) ;
#line 345 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__is_overspecific(action_pattern *ap) ;
#line 355 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__coerce_TEST_ACTION_to_TRY_ACTION(specification *spec, action_pattern *ap) ;
#line 361 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__suppress_action_testing(action_pattern *ap) ;
#line 369 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__categorise_as(action_pattern *ap, int w1, int w2) ;
#line 398 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__clear_validation_case(void) ;
#line 404 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__get_validation_case(specification **spec, kind **set_K, kind **set_K2) ;
#line 415 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__suspend_validation(int state) ;
#line 419 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__validate_parameter(specification *spec, kind *K) ;
#line 458 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__validate_when(specification *spec) ;
#line 467 "inform7/Chapter 24/Action Patterns.w"
specification * nullify_nonspecific_references(specification *spec) ;
#line 473 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__check_going(specification *spec, char *keyword, kind *ka, kind *kb) ;
#line 514 "inform7/Chapter 24/Action Patterns.w"
action_pattern Plugins__Actions__Patterns__parse_parametric(int aw1, int aw2, kind *K) ;
#line 525 "inform7/Chapter 24/Action Patterns.w"
specification * parse_action_parameter(int w1, int w2) ;
#line 530 "inform7/Chapter 24/Action Patterns.w"
specification * parse_verified_action_parameter(int w1, int w2) ;
#line 710 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__suppress(void) ;
#line 716 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__resume(int old_state) ;
#line 771 "inform7/Chapter 24/Action Patterns.w"
action_pattern * ap_parse_inner(int w1, int w2, int tense) ;
#line 984 "inform7/Chapter 24/Action Patterns.w"
action_pattern parse_action_pattern_dash(int w1, int w2) ;
#line 1303 "inform7/Chapter 24/Action Patterns.w"
int ap_count_rooms(action_pattern *ap) ;
#line 1311 "inform7/Chapter 24/Action Patterns.w"
int ap_count_going(action_pattern *ap) ;
#line 1319 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__count_aspects(action_pattern *ap) ;
#line 1342 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__compare_specificity(action_pattern *ap1, action_pattern *ap2) ;
#line 1464 "inform7/Chapter 24/Action Patterns.w"
void put_action_object_into_ap(action_pattern *ap, int pos, int w1, int w2) ;
#line 1494 "inform7/Chapter 24/Action Patterns.w"
int CAP_insert_clause(int f, OUTPUT_STREAM, char *i6_condition) ;
#line 1520 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__compile_pattern_match_clause(int f, OUTPUT_STREAM, nonlocal_variable *I6_global_variable, specification *spec, kind *verify_as_kind, int adapt_region) ;
#line 1646 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__as_stored_action(OUTPUT_STREAM, action_pattern *ap) ;
#line 1677 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__compile_pattern_match(OUTPUT_STREAM, action_pattern ap, int naming_mode) ;
#line 1872 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__refers_to_past(action_pattern *ap) ;
#line 1877 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__convert_to_present_tense(action_pattern *ap) ;
#line 1881 "inform7/Chapter 24/Action Patterns.w"
int pta_acceptable(specification *spec) ;
#line 1890 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__makes_callings(action_pattern *ap) ;
#line 1900 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__compile_present_tense(OUTPUT_STREAM, action_pattern *ap) ;
#line 1904 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__compile_past_tense(OUTPUT_STREAM, action_pattern *ap) ;
#line 24 "inform7/Chapter 24/Looping Over Scope.w"
loop_over_scope * Plugins__Actions__ScopeLoops__new(specification *what) ;
#line 32 "inform7/Chapter 24/Looping Over Scope.w"
int Plugins__Actions__ScopeLoops__compilation_coroutine(OUTPUT_STREAM) ;
#line 27 "inform7/Chapter 24/Named Action Patterns.w"
named_action_pattern * nap_new(int w1, int w2) ;
#line 38 "inform7/Chapter 24/Named Action Patterns.w"
named_action_pattern * Plugins__Actions__Patterns__Named__by_name(int w1, int w2) ;
#line 44 "inform7/Chapter 24/Named Action Patterns.w"
char * Plugins__Actions__Patterns__Named__identifier(named_action_pattern *nap) ;
#line 48 "inform7/Chapter 24/Named Action Patterns.w"
void Plugins__Actions__Patterns__Named__add(action_pattern *app, int w1, int w2) ;
#line 63 "inform7/Chapter 24/Named Action Patterns.w"
int Plugins__Actions__Patterns__Named__within_action_context(named_action_pattern *nap, action_name *an) ;
#line 70 "inform7/Chapter 24/Named Action Patterns.w"
void Plugins__Actions__Patterns__Named__index(void) ;
#line 97 "inform7/Chapter 24/Named Action Patterns.w"
void Plugins__Actions__Patterns__Named__compile(OUTPUT_STREAM) ;
#line 39 "inform7/Chapter 24/Actions Index.w"
void index_meta_verb(char *t) ;
#line 48 "inform7/Chapter 24/Actions Index.w"
void Plugins__Actions__Index__test_verb(char *t) ;
#line 57 "inform7/Chapter 24/Actions Index.w"
void Plugins__Actions__Index__verb_definition(char *p, char *trueverb, int true_verb_wn) ;
#line 81 "inform7/Chapter 24/Actions Index.w"
command_index_entry * Plugins__Actions__Index__vie_new_from(char *headword, grammar_verb *gv, int nature) ;
#line 91 "inform7/Chapter 24/Actions Index.w"
void Plugins__Actions__Index__commands(void) ;
#line 152 "inform7/Chapter 24/Actions Index.w"
void Plugins__Actions__Index__alphabetical(void) ;
#line 218 "inform7/Chapter 24/Actions Index.w"
int compare_action_names(const void *ent1, const void *ent2) ;
#line 227 "inform7/Chapter 24/Actions Index.w"
void Plugins__Actions__Index__page(void) ;
#line 240 "inform7/Chapter 24/Actions Index.w"
void Plugins__Actions__Index__detail_pages(void) ;
#line 262 "inform7/Chapter 24/Actions Index.w"
void Plugins__Actions__Index__tokens(void) ;
#line 101 "inform7/Chapter 24/Activities.w"
void create_activity(parse_node *pn) ;
#line 150 "inform7/Chapter 24/Activities.w"
activity * Code__Activities__new(kind *creation_kind, int w1, int w2) ;
#line 237 "inform7/Chapter 24/Activities.w"
specification * Code__Activities__to_specification(activity *av) ;
#line 245 "inform7/Chapter 24/Activities.w"
activity * Code__Activities__from_specification(specification *spec) ;
#line 281 "inform7/Chapter 24/Activities.w"
void Code__Activities__add_variable(activity *av, parse_node *cnode) ;
#line 365 "inform7/Chapter 24/Activities.w"
void Code__Activities__activity_var_creators_array(OUTPUT_STREAM) ;
#line 383 "inform7/Chapter 24/Activities.w"
void Code__Activities__index_by_number(int id, int indent) ;
#line 389 "inform7/Chapter 24/Activities.w"
void Code__Activities__index(activity *av, int indent) ;
#line 405 "inform7/Chapter 24/Activities.w"
int Code__Activities__no_rules(activity *av) ;
#line 413 "inform7/Chapter 24/Activities.w"
void Code__Activities__index_details(activity *av) ;
#line 421 "inform7/Chapter 24/Activities.w"
char * Code__Activities__identifier(activity *av) ;
#line 425 "inform7/Chapter 24/Activities.w"
int Code__Activities__Lists__count(activity_list *avl) ;
#line 567 "inform7/Chapter 24/Activities.w"
activity_list * Code__Activities__Lists__parse(int w1, int w2) ;
#line 571 "inform7/Chapter 24/Activities.w"
activity_list * Code__Activities__Lists__parse_without_conditions(int w1, int w2) ;
#line 586 "inform7/Chapter 24/Activities.w"
activity_list * Code__Activities__Lists__parse_inner(int w1, int w2, int state) ;
#line 595 "inform7/Chapter 24/Activities.w"
void Code__Activities__compile_activity_list(OUTPUT_STREAM, activity_list *al) ;
#line 623 "inform7/Chapter 24/Activities.w"
void Code__Activities__compile_activity_constants(OUTPUT_STREAM) ;
#line 630 "inform7/Chapter 24/Activities.w"
void Code__Activities__Activity_before_rulebooks_array(OUTPUT_STREAM) ;
#line 640 "inform7/Chapter 24/Activities.w"
void Code__Activities__Activity_for_rulebooks_array(OUTPUT_STREAM) ;
#line 650 "inform7/Chapter 24/Activities.w"
void Code__Activities__Activity_after_rulebooks_array(OUTPUT_STREAM) ;
#line 660 "inform7/Chapter 24/Activities.w"
void Code__Activities__Activity_atb_rulebooks_array(OUTPUT_STREAM) ;
#line 671 "inform7/Chapter 24/Activities.w"
void Code__Activities__Lists__annotate_for_cross_references(activity_list *avl, phrase *ph) ;
#line 682 "inform7/Chapter 24/Activities.w"
void av_index_cross_references(activity *av) ;
#line 63 "inform7/Chapter 25/Traverse for Grammar.w"
void Plugins__Parsing__traverse(void) ;
#line 90 "inform7/Chapter 25/Traverse for Grammar.w"
void Plugins__Parsing__compile_understanding(OUTPUT_STREAM, int w1, int w2, int table_entry) ;
#line 450 "inform7/Chapter 25/Traverse for Grammar.w"
void understand_sentence(int w1, int w2, int as1, int as2) ;
#line 528 "inform7/Chapter 25/Traverse for Grammar.w"
void understand_the_command(int w1, int w2, int wn) ;
#line 587 "inform7/Chapter 25/Traverse for Grammar.w"
void understand_property_block(property *pr, int level, inference_subject *subj, int when1, int when2) ;
#line 614 "inform7/Chapter 25/Traverse for Grammar.w"
void understand_nothing(understanding_reference *ur, int when1, int when2) ;
#line 635 "inform7/Chapter 25/Traverse for Grammar.w"
void understand_block(int w1, int w2, understanding_reference *ur, int when1, int when2, int table_entry) ;
#line 896 "inform7/Chapter 25/Traverse for Grammar.w"
int valid_new_token_name(int w1, int w2) ;
#line 54 "inform7/Chapter 25/Grammar Properties.w"
parsing_data * parsing_plugin_new_data(inference_subject *subj) ;
#line 60 "inform7/Chapter 25/Grammar Properties.w"
parsing_pp_data * parsing_plugin_new_pp_data(property_permission *pp) ;
#line 72 "inform7/Chapter 25/Grammar Properties.w"
void Plugins__Parsing__start(void) ;
#line 80 "inform7/Chapter 25/Grammar Properties.w"
int parsing_new_subject_notify(inference_subject *subj) ;
#line 85 "inform7/Chapter 25/Grammar Properties.w"
int parsing_new_permission_notify(property_permission *new_pp) ;
#line 110 "inform7/Chapter 25/Grammar Properties.w"
int parsing_new_variable_notify(nonlocal_variable *var) ;
#line 135 "inform7/Chapter 25/Grammar Properties.w"
int parsing_estimate_property_usage(kind *k, int *words_used) ;
#line 149 "inform7/Chapter 25/Grammar Properties.w"
int parsing_complete_model(int stage) ;
#line 282 "inform7/Chapter 25/Grammar Properties.w"
int Plugins__Parsing__Visibility__seek(property *pr, inference_subject *subj, int level, int when1, int when2) ;
#line 300 "inform7/Chapter 25/Grammar Properties.w"
int Plugins__Parsing__Visibility__any_property_visible_to_subject(inference_subject *subj, int allow_inheritance) ;
#line 311 "inform7/Chapter 25/Grammar Properties.w"
int Plugins__Parsing__Visibility__get_level(property_permission *pp) ;
#line 315 "inform7/Chapter 25/Grammar Properties.w"
specification * Plugins__Parsing__Visibility__get_condition(property_permission *pp) ;
#line 337 "inform7/Chapter 25/Grammar Properties.w"
void log_parsing_visibility(inference_subject *infs) ;
#line 354 "inform7/Chapter 25/Grammar Properties.w"
int Plugins__Parsing__is_an_action_variable(specification *spec) ;
#line 89 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb * gv_new(int gv_is) ;
#line 109 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__log(grammar_verb *gv) ;
#line 150 "inform7/Chapter 25/Grammar Verbs.w"
int Plugins__Parsing__Verbs__get_verb_wn(grammar_verb *gv) ;
#line 154 "inform7/Chapter 25/Grammar Verbs.w"
int gv_is_genuinely_verbal(grammar_verb *gv) ;
#line 166 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb * Plugins__Parsing__Verbs__find_or_create_command(int vw) ;
#line 186 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb * Plugins__Parsing__Verbs__find_command(int vw) ;
#line 216 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__add_command(grammar_verb *gv, int wn) ;
#line 233 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__remove_command(grammar_verb *gv, int wn) ;
#line 264 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__index_command_aliases(grammar_verb *gv) ;
#line 271 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__remove_action(grammar_verb *gv, action_name *an) ;
#line 279 "inform7/Chapter 25/Grammar Verbs.w"
void gv_compile_Verb_directive_header(OUTPUT_STREAM, grammar_verb *gv) ;
#line 314 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__reserve(char *verb_name) ;
#line 320 "inform7/Chapter 25/Grammar Verbs.w"
int command_verb_reserved(char *verb_tried) ;
#line 330 "inform7/Chapter 25/Grammar Verbs.w"
void normalise_cv_to(char *from, char *to) ;
#line 347 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__make_command_index_entries(grammar_verb *gv) ;
#line 359 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__index_normal(grammar_verb *gv, char *headword) ;
#line 363 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__index_alias(grammar_verb *gv, char *headword) ;
#line 376 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb * Plugins__Parsing__Verbs__named_token_new(int w1, int w2) ;
#line 388 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb * Plugins__Parsing__Verbs__named_token_by_name(int w1, int w2) ;
#line 401 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__index_tokens(void) ;
#line 421 "inform7/Chapter 25/Grammar Verbs.w"
void index_tokens_for(int w1, int w2, char *special, parse_node *where, grammar_line *defns, char *help, char *explanation) ;
#line 438 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__translates(int w1, int w2, parse_node *p2) ;
#line 452 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__compile_i6_token(OUTPUT_STREAM, grammar_verb *gv) ;
#line 465 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb * Plugins__Parsing__Verbs__consultation_new(void) ;
#line 478 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb * Plugins__Parsing__Verbs__for_subject(inference_subject *subj) ;
#line 488 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__take_out_one_word_grammar(OUTPUT_STREAM, grammar_verb *gv) ;
#line 494 "inform7/Chapter 25/Grammar Verbs.w"
int Plugins__Parsing__Verbs__allow_mixed_lines(grammar_verb *gv) ;
#line 505 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb * Plugins__Parsing__Verbs__for_kind(kind *K) ;
#line 521 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb * Plugins__Parsing__Verbs__for_prn(property *prn) ;
#line 537 "inform7/Chapter 25/Grammar Verbs.w"
int Plugins__Parsing__Verbs__is_empty(grammar_verb *gv) ;
#line 542 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__add_line(grammar_verb *gv, grammar_line *gl) ;
#line 564 "inform7/Chapter 25/Grammar Verbs.w"
kind * Plugins__Parsing__Verbs__get_data_type_as_token(grammar_verb *gv) ;
#line 573 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__compile_conditions(OUTPUT_STREAM) ;
#line 586 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__prepare(void) ;
#line 596 "inform7/Chapter 25/Grammar Verbs.w"
void gv_slash_all(void) ;
#line 612 "inform7/Chapter 25/Grammar Verbs.w"
void gv_determine_all(void) ;
#line 623 "inform7/Chapter 25/Grammar Verbs.w"
specification * Plugins__Parsing__Verbs__determine(grammar_verb *gv, int depth) ;
#line 670 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__compile_all(OUTPUT_STREAM) ;
#line 716 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__compile(OUTPUT_STREAM, grammar_verb *gv) ;
#line 776 "inform7/Chapter 25/Grammar Verbs.w"
void gv_compile_parse_name_lines(OUTPUT_STREAM, grammar_verb *gv) ;
#line 799 "inform7/Chapter 25/Grammar Verbs.w"
void gv_compile_lines(OUTPUT_STREAM, grammar_verb *gv) ;
#line 814 "inform7/Chapter 25/Grammar Verbs.w"
void sort_grammar_verb(grammar_verb *gv) ;
#line 80 "inform7/Chapter 25/Grammar Lines.w"
grammar_line * Plugins__Parsing__Lines__new(int wn, action_name *ac, parse_node *token_list, int reversed, int pluralised) ;
#line 109 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__log(grammar_line *gl) ;
#line 114 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__set_single_type(grammar_line *gl, specification *gl_value) ;
#line 123 "inform7/Chapter 25/Grammar Lines.w"
int Plugins__Parsing__Lines__list_length(grammar_line *list_head) ;
#line 130 "inform7/Chapter 25/Grammar Lines.w"
grammar_line * Plugins__Parsing__Lines__list_add(grammar_line *list_head, grammar_line *new_gl) ;
#line 141 "inform7/Chapter 25/Grammar Lines.w"
grammar_line * Plugins__Parsing__Lines__list_remove(grammar_line *list_head, action_name *find) ;
#line 167 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__line_list_compile_condition_tokens(OUTPUT_STREAM, grammar_line *list_head) ;
#line 231 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__set_understand_when(grammar_line *gl, int w1, int w2) ;
#line 236 "inform7/Chapter 25/Grammar Lines.w"
void gl_compile_condition_token_as_needed(OUTPUT_STREAM, grammar_line *gl) ;
#line 263 "inform7/Chapter 25/Grammar Lines.w"
void gl_compile_extra_token_for_condition(OUTPUT_STREAM, grammar_line *gl, int gv_is, int current_label) ;
#line 296 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__set_mistake(grammar_line *gl, int wn) ;
#line 301 "inform7/Chapter 25/Grammar Lines.w"
void gl_compile_mistake_token_as_needed(OUTPUT_STREAM, grammar_line *gl) ;
#line 312 "inform7/Chapter 25/Grammar Lines.w"
void gl_compile_extra_token_for_mistake(OUTPUT_STREAM, grammar_line *gl, int gv_is, int current_label) ;
#line 322 "inform7/Chapter 25/Grammar Lines.w"
int gl_compile_result_of_mistake(OUTPUT_STREAM, grammar_line *gl) ;
#line 327 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__MistakeActionSub_routine(OUTPUT_STREAM) ;
#line 360 "inform7/Chapter 25/Grammar Lines.w"
int gl_contains_single_unconditional_word(grammar_line *gl) ;
#line 382 "inform7/Chapter 25/Grammar Lines.w"
grammar_line * Plugins__Parsing__Lines__list_take_out_one_word_grammar(OUTPUT_STREAM, grammar_line *list_head) ;
#line 403 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__line_list_slash(grammar_line *gl_head) ;
#line 423 "inform7/Chapter 25/Grammar Lines.w"
void slash_grammar_line(grammar_line *gl) ;
#line 500 "inform7/Chapter 25/Grammar Lines.w"
specification * Plugins__Parsing__Lines__line_list_determine(grammar_line *list_head, int depth, int gv_is, grammar_verb *gv, int genuinely_verbal) ;
#line 553 "inform7/Chapter 25/Grammar Lines.w"
specification * gl_determine(grammar_line *gl, int depth, int gv_is, grammar_verb *gv, int genuinely_verbal) ;
#line 629 "inform7/Chapter 25/Grammar Lines.w"
grammar_line * Plugins__Parsing__Lines__list_sort(grammar_line *list_head) ;
#line 822 "inform7/Chapter 25/Grammar Lines.w"
int grammar_line_must_precede(grammar_line *L1, grammar_line *L2) ;
#line 879 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__sorted_line_list_compile(OUTPUT_STREAM, grammar_line *list_head, int gv_is, grammar_verb *gv, int genuinely_verbal) ;
#line 899 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__reset_labels(void) ;
#line 911 "inform7/Chapter 25/Grammar Lines.w"
void compile_grammar_line(OUTPUT_STREAM, grammar_line *gl, int gv_is, grammar_verb *gv, int genuinely_verbal) ;
#line 1019 "inform7/Chapter 25/Grammar Lines.w"
void 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 1134 "inform7/Chapter 25/Grammar Lines.w"
void compile_slash_gprs(OUTPUT_STREAM) ;
#line 1155 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__sorted_list_index_normal(grammar_line *list_head, char *headword) ;
#line 1161 "inform7/Chapter 25/Grammar Lines.w"
void gl_index_normal(grammar_line *gl, char *headword) ;
#line 1195 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__list_assert_ownership(grammar_line *list_head, grammar_verb *gv) ;
#line 1204 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__list_with_action_add(grammar_line *list_head, grammar_line *gl) ;
#line 1215 "inform7/Chapter 25/Grammar Lines.w"
int Plugins__Parsing__Lines__index_list_with_action(grammar_line *gl) ;
#line 1240 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__index_list_for_token(grammar_line *gl) ;
#line 27 "inform7/Chapter 25/Grammar Types.w"
grammar_type Plugins__Parsing__Tokens__Types__new(int supports_return_type) ;
#line 45 "inform7/Chapter 25/Grammar Types.w"
int Plugins__Parsing__Tokens__Types__add_type(grammar_type *gty, specification *spec, int multiple_flag) ;
#line 65 "inform7/Chapter 25/Grammar Types.w"
int Plugins__Parsing__Tokens__Types__has_return_type(grammar_type *gty) ;
#line 70 "inform7/Chapter 25/Grammar Types.w"
int Plugins__Parsing__Tokens__Types__get_no_resulting_values(grammar_type *gty) ;
#line 74 "inform7/Chapter 25/Grammar Types.w"
specification * Plugins__Parsing__Tokens__Types__get_single_type(grammar_type *gty) ;
#line 83 "inform7/Chapter 25/Grammar Types.w"
void Plugins__Parsing__Tokens__Types__set_single_type(grammar_type *gty, specification *spec) ;
#line 91 "inform7/Chapter 25/Grammar Types.w"
void Plugins__Parsing__Tokens__Types__compile_to_string(OUTPUT_STREAM, grammar_type *gty) ;
#line 95 "inform7/Chapter 25/Grammar Types.w"
kind * Plugins__Parsing__Tokens__Types__get_data_type_as_token(grammar_type *gty) ;
#line 109 "inform7/Chapter 25/Grammar Types.w"
int Plugins__Parsing__Tokens__Types__must_precede(grammar_type *gty1, grammar_type *gty2) ;
#line 80 "inform7/Chapter 25/Grammar Tokens.w"
void Plugins__Parsing__Tokens__break_into_tokens(parse_node *pn, int w1, int w2) ;
#line 114 "inform7/Chapter 25/Grammar Tokens.w"
int Plugins__Parsing__Tokens__is_literal(parse_node *pn) ;
#line 123 "inform7/Chapter 25/Grammar Tokens.w"
int Plugins__Parsing__Tokens__is_multiple(parse_node *pn) ;
#line 137 "inform7/Chapter 25/Grammar Tokens.w"
int Plugins__Parsing__Tokens__is_text(parse_node *pn) ;
#line 150 "inform7/Chapter 25/Grammar Tokens.w"
int gsb_for_special_token(int gtc) ;
#line 168 "inform7/Chapter 25/Grammar Tokens.w"
char * i6_token_for_special_token(int gtc) ;
#line 183 "inform7/Chapter 25/Grammar Tokens.w"
char * i6_constant_for_special_token(int gtc) ;
#line 202 "inform7/Chapter 25/Grammar Tokens.w"
kind * kind_for_special_token(int gtc) ;
#line 315 "inform7/Chapter 25/Grammar Tokens.w"
void incompatible_change_problem(char *token_tried, char *token_instead, char *token_better) ;
#line 374 "inform7/Chapter 25/Grammar Tokens.w"
specification * Plugins__Parsing__Tokens__determine(parse_node *pn, int depth) ;
#line 473 "inform7/Chapter 25/Grammar Tokens.w"
kind * Plugins__Parsing__Tokens__compile(OUTPUT_STREAM, parse_node *pn, int code_mode, char *failure_label, int consult_mode) ;
#line 32 "inform7/Chapter 25/Noun Filter Tokens.w"
noun_filter_token * nft_new(specification *spec, int global_scope) ;
#line 46 "inform7/Chapter 25/Noun Filter Tokens.w"
void nft_compile_routine_name(OUTPUT_STREAM, noun_filter_token *nft) ;
#line 50 "inform7/Chapter 25/Noun Filter Tokens.w"
void nft_compile_routine(OUTPUT_STREAM, noun_filter_token *nft) ;
#line 114 "inform7/Chapter 25/Noun Filter Tokens.w"
int Plugins__Parsing__Tokens__Filters__new_id(specification *spec, int global_scope) ;
#line 130 "inform7/Chapter 25/Noun Filter Tokens.w"
void Plugins__Parsing__Tokens__Filters__compile_id(OUTPUT_STREAM, int id, int code_mode) ;
#line 152 "inform7/Chapter 25/Noun Filter Tokens.w"
void Plugins__Parsing__Tokens__Filters__compile(OUTPUT_STREAM) ;
#line 19 "inform7/Chapter 25/Tokens Parsing Values.w"
void Plugins__Parsing__Tokens__Values__number(OUTPUT_STREAM) ;
#line 24 "inform7/Chapter 25/Tokens Parsing Values.w"
void Plugins__Parsing__Tokens__Values__time(OUTPUT_STREAM) ;
#line 32 "inform7/Chapter 25/Tokens Parsing Values.w"
void Plugins__Parsing__Tokens__Values__truth_state(OUTPUT_STREAM) ;
#line 37 "inform7/Chapter 25/Tokens Parsing Values.w"
void Plugins__Parsing__Tokens__Values__compile_type_gprs(OUTPUT_STREAM) ;
#line 123 "inform7/Chapter 25/Tokens Parsing Values.w"
void Plugins__Parsing__Tokens__Values__gprv_compile(OUTPUT_STREAM, kind *K) ;
#line 126 "inform7/Chapter 25/Tokens Parsing Values.w"
void Plugins__Parsing__Tokens__Values__igprv_compile(OUTPUT_STREAM, kind *K) ;
#line 27 "inform7/Chapter 25/General Parsing Routines.w"
STREAM * Plugins__Parsing__Tokens__General__compile_gpr_head(OUTPUT_STREAM, int id) ;
#line 38 "inform7/Chapter 25/General Parsing Routines.w"
STREAM * Plugins__Parsing__Tokens__General__compile_gpr_tail(OUTPUT_STREAM) ;
#line 44 "inform7/Chapter 25/General Parsing Routines.w"
STREAM * Plugins__Parsing__Tokens__General__compile_prn_pr_head(OUTPUT_STREAM, property *prn) ;
#line 55 "inform7/Chapter 25/General Parsing Routines.w"
STREAM * Plugins__Parsing__Tokens__General__compile_prn_pr_tail(OUTPUT_STREAM, property *prn) ;
#line 73 "inform7/Chapter 25/General Parsing Routines.w"
grammar_verb * Plugins__Parsing__Tokens__General__get_consultation_gv(void) ;
#line 78 "inform7/Chapter 25/General Parsing Routines.w"
void Plugins__Parsing__Tokens__General__prepare_consultation_gv(void) ;
#line 82 "inform7/Chapter 25/General Parsing Routines.w"
int Plugins__Parsing__Tokens__General__print_consultation_gv_name(OUTPUT_STREAM) ;
#line 96 "inform7/Chapter 25/General Parsing Routines.w"
STREAM * Plugins__Parsing__Tokens__General__compile_consult_head(OUTPUT_STREAM, int id) ;
#line 110 "inform7/Chapter 25/General Parsing Routines.w"
STREAM * Plugins__Parsing__Tokens__General__compile_consult_tail(OUTPUT_STREAM) ;
#line 132 "inform7/Chapter 25/General Parsing Routines.w"
STREAM * Plugins__Parsing__Tokens__General__compile_parse_name_property(inference_subject *subj) ;
#line 198 "inform7/Chapter 25/General Parsing Routines.w"
STREAM * Plugins__Parsing__Tokens__General__compile_parse_name_head(OUTPUT_STREAM, inference_subject *subj, grammar_verb *gv) ;
#line 240 "inform7/Chapter 25/General Parsing Routines.w"
STREAM * top_of_head(OUTPUT_STREAM, int id, inference_subject *subj, int test_distinguishability, int sometimes_has_visible_properties) ;
#line 291 "inform7/Chapter 25/General Parsing Routines.w"
void Plugins__Parsing__Tokens__General__after_gl_failed(OUTPUT_STREAM, int label, int pluralised) ;
#line 304 "inform7/Chapter 25/General Parsing Routines.w"
STREAM * Plugins__Parsing__Tokens__General__compile_parse_name_tail(OUTPUT_STREAM) ;
#line 335 "inform7/Chapter 25/General Parsing Routines.w"
void consider_visible_properties(OUTPUT_STREAM, inference_subject *subj, int test_distinguishability) ;
#line 363 "inform7/Chapter 25/General Parsing Routines.w"
void start_considering_visible_properties(OUTPUT_STREAM, int phase) ;
#line 367 "inform7/Chapter 25/General Parsing Routines.w"
void consider_visible_property(OUTPUT_STREAM, inference_subject *subj, property *pr, property_permission *pp, int phase) ;
#line 401 "inform7/Chapter 25/General Parsing Routines.w"
void finish_considering_visible_properties(OUTPUT_STREAM, int phase) ;
#line 420 "inform7/Chapter 25/General Parsing Routines.w"
void begin_distinguishing_visible_properties(OUTPUT_STREAM) ;
#line 428 "inform7/Chapter 25/General Parsing Routines.w"
void test_distinguish_visible_property(OUTPUT_STREAM, STREAM *COND) ;
#line 439 "inform7/Chapter 25/General Parsing Routines.w"
void distinguish_visible_property(OUTPUT_STREAM, property *prn) ;
#line 462 "inform7/Chapter 25/General Parsing Routines.w"
void finish_distinguishing_visible_properties(OUTPUT_STREAM) ;
#line 473 "inform7/Chapter 25/General Parsing Routines.w"
void begin_parsing_visible_properties(OUTPUT_STREAM) ;
#line 479 "inform7/Chapter 25/General Parsing Routines.w"
void test_parse_visible_property(OUTPUT_STREAM, STREAM *COND) ;
#line 486 "inform7/Chapter 25/General Parsing Routines.w"
void parse_visible_property(OUTPUT_STREAM, inference_subject *subj, property *prn, int visibility_level) ;
#line 527 "inform7/Chapter 25/General Parsing Routines.w"
void parse_visible_either_or(OUTPUT_STREAM, property *prn, int visibility_level, int pass_l) ;
#line 545 "inform7/Chapter 25/General Parsing Routines.w"
void pvp_test_begins(OUTPUT_STREAM) ;
#line 549 "inform7/Chapter 25/General Parsing Routines.w"
void pvp_test_words(OUTPUT_STREAM, int w1, int w2) ;
#line 560 "inform7/Chapter 25/General Parsing Routines.w"
void pvp_test_passes(OUTPUT_STREAM, int visibility_level, int pass_l) ;
#line 569 "inform7/Chapter 25/General Parsing Routines.w"
void finish_parsing_visible_properties(OUTPUT_STREAM) ;
#line 229 "inform7/Chapter 25/Test Scripts.w"
void new_test_text(parse_node *PN) ;
#line 275 "inform7/Chapter 25/Test Scripts.w"
void check_test_command(char *p) ;
#line 295 "inform7/Chapter 25/Test Scripts.w"
void Plugins__Parsing__TestScripts__write_text(OUTPUT_STREAM) ;
#line 318 "inform7/Chapter 25/Test Scripts.w"
void Plugins__Parsing__TestScripts__compile_switch(OUTPUT_STREAM) ;
#line 332 "inform7/Chapter 25/Test Scripts.w"
void Plugins__Parsing__TestScripts__compile_printout(OUTPUT_STREAM) ;
#line 342 "inform7/Chapter 25/Test Scripts.w"
void new_internal_test_case(int code, int x1, int x2) ;
#line 350 "inform7/Chapter 25/Test Scripts.w"
void Plugins__Parsing__TestScripts__InternalTestCases_routine(OUTPUT_STREAM) ;
#line 440 "inform7/Chapter 25/Test Scripts.w"
void Plugins__Parsing__TestScripts__Internal__begin_reporting(void) ;
#line 444 "inform7/Chapter 25/Test Scripts.w"
void Plugins__Parsing__TestScripts__Internal__end_reporting(void) ;
#line 448 "inform7/Chapter 25/Test Scripts.w"
void Plugins__Parsing__TestScripts__Internal__showme(OUTPUT_STREAM, specification *spec) ;
#line 45 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__start(void) ;
#line 53 "inform7/Chapter 26/Figures.w"
int figures_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) ;
#line 62 "inform7/Chapter 26/Figures.w"
int figures_new_named_instance_notify(instance *nc) ;
#line 78 "inform7/Chapter 26/Figures.w"
blorb_figure * new_blorb_figure(instance *nc) ;
#line 93 "inform7/Chapter 26/Figures.w"
void handle_figure_definition(parse_node *p) ;
#line 135 "inform7/Chapter 26/Figures.w"
void register_figure(int f1, int f2, int fn1, int fn2) ;
#line 174 "inform7/Chapter 26/Figures.w"
char * Plugins__Figures__description_of_cover_art(void) ;
#line 185 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__write_picture_manifest(OUTPUT_STREAM, int releasing_cover) ;
#line 214 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__write_blurb_commands(OUTPUT_STREAM, char *resources) ;
#line 237 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__write_copy_commands(void) ;
#line 249 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__tableoffigures_array(OUTPUT_STREAM) ;
#line 265 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__index_all(void) ;
#line 41 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__start(void) ;
#line 49 "inform7/Chapter 26/Sound Effects.w"
int sounds_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) ;
#line 58 "inform7/Chapter 26/Sound Effects.w"
int sounds_new_named_instance_notify(instance *nc) ;
#line 74 "inform7/Chapter 26/Sound Effects.w"
blorb_sound * new_blorb_sound(instance *nc) ;
#line 85 "inform7/Chapter 26/Sound Effects.w"
void handle_sound_definition(parse_node *p) ;
#line 118 "inform7/Chapter 26/Sound Effects.w"
void register_sound(int f1, int f2, int fn1, int fn2) ;
#line 161 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__write_sounds_manifest(OUTPUT_STREAM) ;
#line 177 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__write_blurb_commands(OUTPUT_STREAM, char *resources) ;
#line 197 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__write_copy_commands(void) ;
#line 208 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__tableofsounds_array(OUTPUT_STREAM) ;
#line 220 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__index_all(void) ;
#line 43 "inform7/Chapter 26/External Files.w"
void Plugins__Files__start(void) ;
#line 52 "inform7/Chapter 26/External Files.w"
int files_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) ;
#line 60 "inform7/Chapter 26/External Files.w"
int files_new_named_instance_notify(instance *nc) ;
#line 79 "inform7/Chapter 26/External Files.w"
external_file * new_external_file(instance *nc) ;
#line 145 "inform7/Chapter 26/External Files.w"
void handle_file_definition(parse_node *p) ;
#line 154 "inform7/Chapter 26/External Files.w"
void register_file(int f1, int f2, int fn1, int fn2) ;
#line 251 "inform7/Chapter 26/External Files.w"
int files_compile_constant(OUTPUT_STREAM, kind *K, specification *spec) ;
#line 269 "inform7/Chapter 26/External Files.w"
void Plugins__Files__arrays(OUTPUT_STREAM) ;
#line 303 "inform7/Chapter 26/External Files.w"
void Plugins__Files__index_all(void) ;
#line 31 "inform7/Chapter 27/Main Routine.w"
int main(int argc, char *argv[]) ;
#line 187 "inform7/Chapter 27/Main Routine.w"
void what_day_is_it(void) ;
#line 194 "inform7/Chapter 27/Main Routine.w"
char * cli_pair(char *wanted, char *got) ;
#line 162 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__interpret(OUTPUT_STREAM, char *sf, char *segment_name, int N_escape) ;
#line 942 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__compile_I7_from_I6(OUTPUT_STREAM, char *p) ;
#line 991 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__new_intervention(int stage, char *segment, char *part, char *i6, char *seg) ;
#line 1019 "inform7/Chapter 27/I6 Template Interpreter.w"
int I6T_file_intervene(OUTPUT_STREAM, int stage, char *segment, char *part) ;
#line 1046 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__report_unacted_upon_interventions(void) ;
#line 1077 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__compile_build_number(OUTPUT_STREAM) ;
#line 1087 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__register_sentence_handlers(void) ;
#line 105 "inform7/Chapter 27/Plugins.w"
word_assemblage plugin_wording(int N) ;
#line 148 "inform7/Chapter 27/Plugins.w"
void Config__Plugins__start(void) ;
#line 201 "inform7/Chapter 27/Plugins.w"
void start_core(void) ;
#line 246 "inform7/Chapter 27/Plugins.w"
void Config__Plugins__plug_in(int w1, int w2) ;
#line 284 "inform7/Chapter 27/Plugins.w"
void Config__Plugins__show_configuration(OUTPUT_STREAM) ;
#line 293 "inform7/Chapter 27/Plugins.w"
void show_plugins(OUTPUT_STREAM, char *label, int state) ;
#line 308 "inform7/Chapter 27/Plugins.w"
void Config__Plugins__define_IFDEF_symbols(OUTPUT_STREAM) ;
#line 318 "inform7/Chapter 27/Plugins.w"
void Config__Plugins__command(char *command) ;
#line 336 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__plugged_in(plugin *P) ;
#line 366 "inform7/Chapter 27/Plugins.w"
void initialise_plugin_calls(void) ;
#line 409 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__name_to_early_infs(int w1, int w2, inference_subject **infs) ;
#line 413 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__new_variable_notify(nonlocal_variable *q) ;
#line 417 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__new_base_kind_notify(kind *K, char *d, int w1, int w2) ;
#line 421 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__compile_constant(OUTPUT_STREAM, kind *K, specification *spec) ;
#line 425 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__new_subject_notify(inference_subject *subj) ;
#line 429 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__new_named_instance_notify(instance *nc) ;
#line 433 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__new_permission_notify(property_permission *pp) ;
#line 437 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__irregular_genitive(inference_subject *owner, char *genitive, int *propriety) ;
#line 441 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__set_kind_notify(instance *I, kind *k) ;
#line 445 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__set_subkind_notify(kind *sub, kind *super) ;
#line 449 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__complete_model(int stage) ;
#line 454 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__parse_composite_NQs(int *w1, int *w2, int *determiner_w1, int *determiner_w2, quantifier **quantifier_used, kind **some_kind) ;
#line 461 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__refine_implicit_noun(parse_node *p) ;
#line 466 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__act_on_special_NPs(parse_node *p) ;
#line 470 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__new_property_notify(property *prn) ;
#line 474 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__property_value_notify(property *prn, specification *val) ;
#line 478 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__more_specific(instance *I1, instance *I2) ;
#line 482 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__inferences_contradict(inference *A, inference *B, int similarity) ;
#line 486 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__explain_contradiction(inference *A, inference *B, int similarity, inference_subject *subj) ;
#line 491 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__intervene_in_assertion(parse_node *px, parse_node *py) ;
#line 495 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__log_inference_type(int it) ;
#line 499 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__compile_object_header(OUTPUT_STREAM, instance *I) ;
#line 503 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__estimate_property_usage(kind *k, int *words_used) ;
#line 507 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__check_going(specification *from, specification *to, specification *by, specification *through, specification *pushing) ;
#line 512 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__compile_model_tables(OUTPUT_STREAM) ;
#line 516 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__default_appearance(inference_subject *infs, specification *txt) ;
#line 520 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__offered_property(kind *K, specification *owner, parse_node *what) ;
#line 524 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__offered_specification(specification *owner, int w1, int w2) ;
#line 528 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__typecheck_equality(kind *K1, kind *K2) ;
#line 532 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__forbid_setting(kind *K) ;
#line 536 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__variable_set_warning(nonlocal_variable *q, specification *val) ;
#line 540 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__detect_bodysnatching(inference_subject *body, int *snatcher, inference_subject **counterpart) ;
#line 545 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__add_to_World_index(instance *O) ;
#line 549 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__annotate_in_World_index(instance *O) ;
#line 85 "inform7/Chapter 2/Make Inform 6 Names.w"
nonterminal *translates_into_i6_sentence_subject_NTM = NULL;
#line 110 "inform7/Chapter 2/Make Inform 6 Names.w"
nonterminal *translates_into_i6_sentence_object_NTM = NULL;
#line 193 "inform7/Chapter 2/Make Inform 6 Names.w"
nonterminal *extra_response_NTM = NULL;
#line 69 "inform7/Chapter 3/HTML Documentation.w"
nonterminal *extension_documentation_heading_NTM = NULL;
#line 97 "inform7/Chapter 3/HTML Documentation.w"
nonterminal *extension_example_header_NTM = NULL;
#line 101 "inform7/Chapter 3/HTML Documentation.w"
nonterminal *row_of_asterisks_NTM = NULL;
#line 304 "inform7/Chapter 3/HTML Documentation.w"
nonterminal *extension_documentation_paste_marker_NTM = NULL;
#line 934 "inform7/Chapter 3/Index File Services.w"
nonterminal *documentation_symbol_tail_NTM = NULL;
#line 938 "inform7/Chapter 3/Index File Services.w"
nonterminal *documentation_symbol_NTM = NULL;
#line 421 "inform7/Chapter 4/Debugging Log.w"
nonterminal *include_in_debugging_sentence_subject_NTM = NULL;
#line 425 "inform7/Chapter 4/Debugging Log.w"
nonterminal *debugging_log_request_NTM = NULL;
#line 95 "inform7/Chapter 5/Lexical Services.w"
nonterminal *if_start_of_paragraph_NTM = NULL;
#line 111 "inform7/Chapter 5/Lexical Services.w"
nonterminal *if_start_of_source_text_NTM = NULL;
#line 120 "inform7/Chapter 5/Lexical Services.w"
nonterminal *if_not_deliberately_capitalised_NTM = NULL;
#line 267 "inform7/Chapter 5/Lexical Services.w"
nonterminal *balanced_text_NTM = NULL;
#line 301 "inform7/Chapter 5/Lexical Services.w"
nonterminal *list_comma_division_NTM = NULL;
#line 618 "inform7/Chapter 5/Tries and Inflections.w"
nonterminal *small_trie_test_NTM = NULL;
#line 286 "inform7/Chapter 5/Natural Languages.w"
nonterminal *natural_language_NTM = NULL;
#line 471 "inform7/Chapter 5/Preform.w"
nonterminal *preform_nonterminal_NTM = NULL;
#line 355 "inform7/Chapter 6/Sentences.w"
nonterminal *dividing_sentence_NTM = NULL;
#line 359 "inform7/Chapter 6/Sentences.w"
nonterminal *heading_NTM = NULL;
#line 366 "inform7/Chapter 6/Sentences.w"
nonterminal *extension_end_marker_sentence_NTM = NULL;
#line 516 "inform7/Chapter 6/Sentences.w"
nonterminal *structural_sentence_NTM = NULL;
#line 533 "inform7/Chapter 6/Sentences.w"
nonterminal *language_modifying_sentence_NTM = NULL;
#line 544 "inform7/Chapter 6/Sentences.w"
nonterminal *use_option_sentence_shape_NTM = NULL;
#line 604 "inform7/Chapter 6/Sentences.w"
nonterminal *comma_divisible_sentence_NTM = NULL;
#line 622 "inform7/Chapter 6/Sentences.w"
nonterminal *list_or_division_NTM = NULL;
#line 222 "inform7/Chapter 6/Virtual Machines.w"
nonterminal *vm_description_list_NTM = NULL;
#line 227 "inform7/Chapter 6/Virtual Machines.w"
nonterminal *vm_description_tail_NTM = NULL;
#line 231 "inform7/Chapter 6/Virtual Machines.w"
nonterminal *vm_description_entry_NTM = NULL;
#line 238 "inform7/Chapter 6/Virtual Machines.w"
nonterminal *version_identification_NTM = NULL;
#line 309 "inform7/Chapter 6/Virtual Machines.w"
nonterminal *virtual_machine_NTM = NULL;
#line 294 "inform7/Chapter 6/Headings.w"
nonterminal *heading_qualifier_NTM = NULL;
#line 300 "inform7/Chapter 6/Headings.w"
nonterminal *bracketed_heading_qualifier_NTM = NULL;
#line 307 "inform7/Chapter 6/Headings.w"
nonterminal *platform_qualifier_NTM = NULL;
#line 311 "inform7/Chapter 6/Headings.w"
nonterminal *platform_identifier_NTM = NULL;
#line 317 "inform7/Chapter 6/Headings.w"
nonterminal *extension_qualifier_NTM = NULL;
#line 323 "inform7/Chapter 6/Headings.w"
nonterminal *extension_identifier_NTM = NULL;
#line 297 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *nonstructural_sentence_NTM = NULL;
#line 496 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *nounphrase_NTM = NULL;
#line 499 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *nounphrase_definite_NTM = NULL;
#line 503 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *nounphrase_figure_NTM = NULL;
#line 506 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *nounphrase_sound_NTM = NULL;
#line 509 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *nounphrase_external_file_NTM = NULL;
#line 512 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *nounphrase_actionable_NTM = NULL;
#line 515 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *variable_creation_tail_NTM = NULL;
#line 522 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *translation_target_NTM = NULL;
#line 549 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *existential_sentence_NTM = NULL;
#line 573 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *existential_sentence_inner_NTM = NULL;
#line 581 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *existential_sentence_inner_tail1_NTM = NULL;
#line 585 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *existential_sentence_inner_tail2_NTM = NULL;
#line 589 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *existential_sentence_inner_tail3_NTM = NULL;
#line 646 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *certainty_NTM = NULL;
#line 704 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_NTM = NULL;
#line 714 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail1_without_rc_NTM = NULL;
#line 720 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail2_without_rc_NTM = NULL;
#line 726 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail3_without_rc_NTM = NULL;
#line 732 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail4_without_rc_NTM = NULL;
#line 738 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail1_NTM = NULL;
#line 742 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail2_NTM = NULL;
#line 746 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail3_NTM = NULL;
#line 750 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail4_NTM = NULL;
#line 784 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail1_inner_NTM = NULL;
#line 790 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail2_inner_NTM = NULL;
#line 796 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail3_inner_NTM = NULL;
#line 802 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *regular_sentence_tail4_inner_NTM = NULL;
#line 853 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *bad_nonstructural_sentence_diagnosis_NTM = NULL;
#line 856 "inform7/Chapter 6/Verb Phrases.w"
nonterminal *bad_nonstructural_sentence_diagnosis_tail_NTM = NULL;
#line 69 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *nounphrase_articled_NTM = NULL;
#line 93 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_balanced_NTM = NULL;
#line 97 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_articled_balanced_NTM = NULL;
#line 130 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *nounphrase_articled_list_NTM = NULL;
#line 135 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_articled_tail_NTM = NULL;
#line 159 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *nounphrase_rule_list_NTM = NULL;
#line 164 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_rule_tail_NTM = NULL;
#line 168 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *nounphrase_rule_NTM = NULL;
#line 178 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *nounphrase_alternative_list_NTM = NULL;
#line 183 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_alternative_tail_NTM = NULL;
#line 202 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *nounphrase_as_object_NTM = NULL;
#line 206 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *nounphrase_as_subject_NTM = NULL;
#line 211 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_inner_NTM = NULL;
#line 219 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *if_copular_NTM = NULL;
#line 258 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_relative_phrase_limited_NTM = NULL;
#line 264 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_relative_phrase_unlimited_NTM = NULL;
#line 278 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_relative_phrase_exception_NTM = NULL;
#line 297 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_relative_phrase_implicit_NTM = NULL;
#line 303 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_relative_phrase_explicit_NTM = NULL;
#line 382 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_inner_without_rp_NTM = NULL;
#line 408 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_with_or_having_tail_NTM = NULL;
#line 413 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_new_property_list_NTM = NULL;
#line 418 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_new_property_NTM = NULL;
#line 421 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_new_property_tail_NTM = NULL;
#line 425 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_tail_NTM = NULL;
#line 437 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_kind_phrase_NTM = NULL;
#line 441 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_kind_phrase_unarticled_NTM = NULL;
#line 454 "inform7/Chapter 6/Noun Phrases.w"
nonterminal *np_from_or_of_tail_NTM = NULL;
#line 232 "inform7/Chapter 6/Of and From.w"
nonterminal *prohibited_property_owners_NTM = NULL;
#line 242 "inform7/Chapter 6/Of and From.w"
nonterminal *action_name_formal_NTM = NULL;
#line 245 "inform7/Chapter 6/Of and From.w"
nonterminal *activity_name_formal_NTM = NULL;
#line 248 "inform7/Chapter 6/Of and From.w"
nonterminal *relation_name_formal_NTM = NULL;
#line 251 "inform7/Chapter 6/Of and From.w"
nonterminal *rule_name_formal_NTM = NULL;
#line 254 "inform7/Chapter 6/Of and From.w"
nonterminal *rulebook_name_formal_NTM = NULL;
#line 267 "inform7/Chapter 6/Of and From.w"
nonterminal *has_properties_called_sentence_object_NTM = NULL;
#line 271 "inform7/Chapter 6/Of and From.w"
nonterminal *has_property_name_tail_NTM = NULL;
#line 275 "inform7/Chapter 6/Of and From.w"
nonterminal *has_property_name_NTM = NULL;
#line 279 "inform7/Chapter 6/Of and From.w"
nonterminal *bad_property_name_diagnosis_NTM = NULL;
#line 335 "inform7/Chapter 6/Of and From.w"
nonterminal *sentence_needing_second_look_NTM = NULL;
#line 616 "inform7/Chapter 6/Rule Subtrees.w"
nonterminal *control_structure_phrase_NTM = NULL;
#line 628 "inform7/Chapter 6/Rule Subtrees.w"
nonterminal *end_control_structure_phrase_NTM = NULL;
#line 636 "inform7/Chapter 6/Rule Subtrees.w"
nonterminal *phrase_beginning_block_NTM = NULL;
#line 77 "inform7/Chapter 7/Including Extensions.w"
nonterminal *extension_title_and_version_NTM = NULL;
#line 82 "inform7/Chapter 7/Including Extensions.w"
nonterminal *extension_unversioned_NTM = NULL;
#line 86 "inform7/Chapter 7/Including Extensions.w"
nonterminal *extension_unversioned_inner_NTM = NULL;
#line 103 "inform7/Chapter 7/Including Extensions.w"
nonterminal *extension_version_NTM = NULL;
#line 251 "inform7/Chapter 7/Including Extensions.w"
nonterminal *extension_body_NTM = NULL;
#line 367 "inform7/Chapter 7/Including Extensions.w"
nonterminal *begins_here_sentence_subject_NTM = NULL;
#line 301 "inform7/Chapter 8/Traverse for Assertions.w"
nonterminal *no_verb_diagnosis_NTM = NULL;
#line 322 "inform7/Chapter 8/Refine Parse Tree.w"
nonterminal *kind_alias_syntax_NTM = NULL;
#line 405 "inform7/Chapter 8/Refine Parse Tree.w"
nonterminal *newfound_property_of_NTM = NULL;
#line 512 "inform7/Chapter 8/Refine Parse Tree.w"
nonterminal *assertion_np_as_value_NTM = NULL;
#line 351 "inform7/Chapter 8/The Creator.w"
nonterminal *grammatical_gender_marker_NTM = NULL;
#line 354 "inform7/Chapter 8/The Creator.w"
nonterminal *grammatical_gender_abbreviation_NTM = NULL;
#line 391 "inform7/Chapter 8/The Creator.w"
nonterminal *creation_problem_diagnosis_NTM = NULL;
#line 938 "inform7/Chapter 8/The Creator.w"
nonterminal *text_ending_with_a_calling_NTM = NULL;
#line 942 "inform7/Chapter 8/The Creator.w"
nonterminal *text_including_a_calling_NTM = NULL;
#line 955 "inform7/Chapter 8/The Creator.w"
nonterminal *unsuitable_name_NTM = NULL;
#line 960 "inform7/Chapter 8/The Creator.w"
nonterminal *unsuitable_name_for_locals_NTM = NULL;
#line 965 "inform7/Chapter 8/The Creator.w"
nonterminal *unfortunate_name_NTM = NULL;
#line 1689 "inform7/Chapter 8/Make Assertions.w"
nonterminal *something_loose_diagnosis_NTM = NULL;
#line 33 "inform7/Chapter 8/Property Declarations.w"
nonterminal *forbidden_property_owners_NTM = NULL;
#line 131 "inform7/Chapter 8/Property Declarations.w"
nonterminal *can_be_sentence_object_NTM = NULL;
#line 137 "inform7/Chapter 8/Property Declarations.w"
nonterminal *condition_name_NTM = NULL;
#line 141 "inform7/Chapter 8/Property Declarations.w"
nonterminal *condition_name_inner_NTM = NULL;
#line 146 "inform7/Chapter 8/Property Declarations.w"
nonterminal *condition_name_innermost_NTM = NULL;
#line 74 "inform7/Chapter 9/English Inflections.w"
nonterminal *singular_noun_to_its_indefinite_article_NTM = NULL;
#line 82 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_indef_a_NTM = NULL;
#line 93 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_indef_b_NTM = NULL;
#line 161 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_indef_c_NTM = NULL;
#line 248 "inform7/Chapter 9/English Inflections.w"
nonterminal *singular_noun_to_its_plural_NTM = NULL;
#line 262 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_plural_uninflected_NTM = NULL;
#line 317 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_plural_pronouns_NTM = NULL;
#line 345 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_plural_irregular_NTM = NULL;
#line 364 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_plural_irregular_inflections_NTM = NULL;
#line 380 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_plural_assimilated_classical_inflections_NTM = NULL;
#line 411 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_plural_irregular_o_suffixes_NTM = NULL;
#line 449 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_plural_regular_inflections_NTM = NULL;
#line 533 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_plural_append_s_NTM = NULL;
#line 653 "inform7/Chapter 9/English Inflections.w"
nonterminal *verb_conjugation_instructions_NTM = NULL;
#line 722 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_have_conjugation_NTM = NULL;
#line 812 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_have_tabulation_NTM = NULL;
#line 823 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_have_present_NTM = NULL;
#line 860 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_do_conjugation_NTM = NULL;
#line 865 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_do_tabulation_NTM = NULL;
#line 876 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_do_present_NTM = NULL;
#line 899 "inform7/Chapter 9/English Inflections.w"
nonterminal *regular_verb_conjugation_NTM = NULL;
#line 917 "inform7/Chapter 9/English Inflections.w"
nonterminal *regular_verb_tabulation_NTM = NULL;
#line 935 "inform7/Chapter 9/English Inflections.w"
nonterminal *regular_verb_present_NTM = NULL;
#line 941 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_be_conjugation_NTM = NULL;
#line 946 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_be_tabulation_NTM = NULL;
#line 956 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_be_present_NTM = NULL;
#line 959 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_be_past_NTM = NULL;
#line 981 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_be_able_to_conjugation_NTM = NULL;
#line 986 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_be_able_to_tabulation_NTM = NULL;
#line 1022 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_be_able_to_auxiliary_NTM = NULL;
#line 1027 "inform7/Chapter 9/English Inflections.w"
nonterminal *to_be_able_to_auxiliary_tabulation_NTM = NULL;
#line 1037 "inform7/Chapter 9/English Inflections.w"
nonterminal *modal_conjugation_NTM = NULL;
#line 1042 "inform7/Chapter 9/English Inflections.w"
nonterminal *modal_tabulation_NTM = NULL;
#line 1081 "inform7/Chapter 9/English Inflections.w"
nonterminal *contracted_to_be_conjugation_NTM = NULL;
#line 1087 "inform7/Chapter 9/English Inflections.w"
nonterminal *contracted_to_be_tabulation_NTM = NULL;
#line 1099 "inform7/Chapter 9/English Inflections.w"
nonterminal *contracted_to_be_present_NTM = NULL;
#line 1102 "inform7/Chapter 9/English Inflections.w"
nonterminal *contracted_to_be_past_NTM = NULL;
#line 1105 "inform7/Chapter 9/English Inflections.w"
nonterminal *contracted_to_be_past_negated_NTM = NULL;
#line 1121 "inform7/Chapter 9/English Inflections.w"
nonterminal *contracted_to_have_conjugation_NTM = NULL;
#line 1127 "inform7/Chapter 9/English Inflections.w"
nonterminal *contracted_to_have_tabulation_NTM = NULL;
#line 1139 "inform7/Chapter 9/English Inflections.w"
nonterminal *contracted_to_have_present_NTM = NULL;
#line 1155 "inform7/Chapter 9/English Inflections.w"
nonterminal *arent_conjugation_NTM = NULL;
#line 1161 "inform7/Chapter 9/English Inflections.w"
nonterminal *arent_tabulation_NTM = NULL;
#line 1168 "inform7/Chapter 9/English Inflections.w"
nonterminal *arent_present_NTM = NULL;
#line 1171 "inform7/Chapter 9/English Inflections.w"
nonterminal *arent_past_NTM = NULL;
#line 1174 "inform7/Chapter 9/English Inflections.w"
nonterminal *arent_perfect_NTM = NULL;
#line 1186 "inform7/Chapter 9/English Inflections.w"
nonterminal *informal_negated_modal_conjugation_NTM = NULL;
#line 1195 "inform7/Chapter 9/English Inflections.w"
nonterminal *informal_negated_modal_tabulation_NTM = NULL;
#line 1202 "inform7/Chapter 9/English Inflections.w"
nonterminal *informal_negated_modal_present_NTM = NULL;
#line 1208 "inform7/Chapter 9/English Inflections.w"
nonterminal *cant_modal_conjugation_NTM = NULL;
#line 1214 "inform7/Chapter 9/English Inflections.w"
nonterminal *cant_modal_tabulation_NTM = NULL;
#line 1230 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_modal_contracted_present_NTM = NULL;
#line 1242 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_modal_contracted_past_NTM = NULL;
#line 1254 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_modal_contracted_future_NTM = NULL;
#line 1314 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_present_participle_NTM = NULL;
#line 1328 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_irregular_present_participle_NTM = NULL;
#line 1518 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_irregular_compound_present_participle_NTM = NULL;
#line 1537 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_regular_a_present_participle_NTM = NULL;
#line 1587 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_regular_b_present_participle_NTM = NULL;
#line 1592 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_regular_c_present_participle_NTM = NULL;
#line 1604 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_past_participle_NTM = NULL;
#line 1608 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_irregular_past_participle_NTM = NULL;
#line 1768 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_present_verb_form_NTM = NULL;
#line 1772 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_irregular_third_person_present_NTM = NULL;
#line 1784 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_past_NTM = NULL;
#line 1791 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_irregular_past_NTM = NULL;
#line 2335 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_irregular_compound_past_NTM = NULL;
#line 2351 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_regular_a_past_NTM = NULL;
#line 2398 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_regular_b_past_NTM = NULL;
#line 2403 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_regular_c_past_NTM = NULL;
#line 2430 "inform7/Chapter 9/English Inflections.w"
nonterminal *pasturise_participle_NTM = NULL;
#line 2435 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_pasturise_exceptions_NTM = NULL;
#line 2899 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_pasturise_regular_y_NTM = NULL;
#line 2902 "inform7/Chapter 9/English Inflections.w"
nonterminal *en_trie_pasturise_regular_NTM = NULL;
#line 2910 "inform7/Chapter 9/English Inflections.w"
nonterminal *adjective_to_plural_NTM = NULL;
#line 2913 "inform7/Chapter 9/English Inflections.w"
nonterminal *adjective_to_masculine_singular_NTM = NULL;
#line 2916 "inform7/Chapter 9/English Inflections.w"
nonterminal *adjective_to_feminine_singular_NTM = NULL;
#line 2919 "inform7/Chapter 9/English Inflections.w"
nonterminal *adjective_to_masculine_plural_NTM = NULL;
#line 2922 "inform7/Chapter 9/English Inflections.w"
nonterminal *adjective_to_feminine_plural_NTM = NULL;
#line 13 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *pronoun_NTM = NULL;
#line 17 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *nominative_pronoun_NTM = NULL;
#line 21 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *accusative_pronoun_NTM = NULL;
#line 33 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *possessive_first_person_NTM = NULL;
#line 37 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *possessive_second_person_NTM = NULL;
#line 41 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *possessive_third_person_NTM = NULL;
#line 52 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *relative_clause_marker_NTM = NULL;
#line 58 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *article_NTM = NULL;
#line 73 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *definite_article_NTM = NULL;
#line 76 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *indefinite_article_NTM = NULL;
#line 83 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *optional_definite_article_NTM = NULL;
#line 87 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *optional_article_NTM = NULL;
#line 91 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *compulsory_article_NTM = NULL;
#line 114 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *non_participles_NTM = NULL;
#line 117 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *probable_participle_NTM = NULL;
#line 128 "inform7/Chapter 9/Articles and Pronouns.w"
nonterminal *negated_clause_NTM = NULL;
#line 305 "inform7/Chapter 9/Determiners and Quantifiers.w"
nonterminal *determiner_names_NTM = NULL;
#line 374 "inform7/Chapter 9/Determiners and Quantifiers.w"
nonterminal *determination_of_NTM = NULL;
#line 392 "inform7/Chapter 9/Determiners and Quantifiers.w"
nonterminal *excluded_from_determiners_NTM = NULL;
#line 700 "inform7/Chapter 9/Binary Predicates.w"
nonterminal *relation_name_NTM = NULL;
#line 66 "inform7/Chapter 9/Relations.w"
nonterminal *relation_names_NTM = NULL;
#line 109 "inform7/Chapter 9/Relations.w"
nonterminal *relates_sentence_subject_NTM = NULL;
#line 256 "inform7/Chapter 9/Relations.w"
nonterminal *relates_sentence_left_object_NTM = NULL;
#line 260 "inform7/Chapter 9/Relations.w"
nonterminal *relates_sentence_right_object_NTM = NULL;
#line 265 "inform7/Chapter 9/Relations.w"
nonterminal *relation_term_right_named_NTM = NULL;
#line 269 "inform7/Chapter 9/Relations.w"
nonterminal *relation_term_right_NTM = NULL;
#line 275 "inform7/Chapter 9/Relations.w"
nonterminal *relation_term_basic_NTM = NULL;
#line 234 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *general_verb_NTM = NULL;
#line 251 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *general_verb_present_positive_NTM = NULL;
#line 273 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *foreign_verb_present_positive_NTM = NULL;
#line 297 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *copular_verb_NTM = NULL;
#line 317 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *copular_verb_present_positive_NTM = NULL;
#line 342 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *negated_noncopular_verb_present_NTM = NULL;
#line 365 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *universal_verb_NTM = NULL;
#line 384 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *possession_verb_present_positive_NTM = NULL;
#line 407 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *negated_verb_NTM = NULL;
#line 427 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *past_tense_verb_NTM = NULL;
#line 468 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *preposition_NTM = NULL;
#line 489 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *preposition_implying_player_NTM = NULL;
#line 594 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *inequality_conjugations_NTM = NULL;
#line 731 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *comparative_property_construction_NTM = NULL;
#line 737 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *same_property_as_construction_NTM = NULL;
#line 745 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *same_property_as_in_lexicon_NTM = NULL;
#line 772 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *verb_implies_sentence_subject_NTM = NULL;
#line 776 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *infinitive_usage_NTM = NULL;
#line 780 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *infinitive_usage_exceptional_NTM = NULL;
#line 789 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *conjugation_NTM = NULL;
#line 802 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *participle_like_NTM = NULL;
#line 818 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *verb_implies_sentence_object_NTM = NULL;
#line 1362 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *adaptive_verb_NTM = NULL;
#line 1379 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *auxiliary_verb_only_NTM = NULL;
#line 1383 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *instance_of_verb_NTM = NULL;
#line 1400 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *not_instance_of_verb_at_run_time_NTM = NULL;
#line 1404 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *modal_verb_NTM = NULL;
#line 1423 "inform7/Chapter 9/Conjugation of Verbs.w"
nonterminal *verb_infinitive_NTM = NULL;
#line 165 "inform7/Chapter 9/Adjectives.w"
nonterminal *adjective_name_NTM = NULL;
#line 1369 "inform7/Chapter 9/Adjectives.w"
nonterminal *adaptive_adjective_NTM = NULL;
#line 1488 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *specifies_sentence_subject_NTM = NULL;
#line 1494 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_group_list_NTM = NULL;
#line 1498 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_group_tail_NTM = NULL;
#line 1502 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_group_NTM = NULL;
#line 1558 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *specifies_sentence_object_NTM = NULL;
#line 1562 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *kind_specified_NTM = NULL;
#line 1566 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_specification_tail_NTM = NULL;
#line 1573 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *scaling_instruction_NTM = NULL;
#line 1599 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_list_NTM = NULL;
#line 1603 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_tail_NTM = NULL;
#line 1607 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_NTM = NULL;
#line 1611 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_option_list_NTM = NULL;
#line 1615 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_option_tail_NTM = NULL;
#line 1619 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_option_NTM = NULL;
#line 1903 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_group_name_NTM = NULL;
#line 72 "inform7/Chapter 10/Times of Day.w"
nonterminal *literal_time_NTM = NULL;
#line 77 "inform7/Chapter 10/Times of Day.w"
nonterminal *elapsed_time_NTM = NULL;
#line 82 "inform7/Chapter 10/Times of Day.w"
nonterminal *clock_time_NTM = NULL;
#line 86 "inform7/Chapter 10/Times of Day.w"
nonterminal *am_pm_NTM = NULL;
#line 112 "inform7/Chapter 10/Times of Day.w"
nonterminal *digital_clock_time_NTM = NULL;
#line 140 "inform7/Chapter 10/Times of Day.w"
nonterminal *continental_clock_time_NTM = NULL;
#line 168 "inform7/Chapter 10/Times of Day.w"
nonterminal *event_rule_preamble_NTM = NULL;
#line 47 "inform7/Chapter 10/Unicode Translations.w"
nonterminal *translates_into_unicode_sentence_subject_NTM = NULL;
#line 57 "inform7/Chapter 10/Unicode Translations.w"
nonterminal *translates_into_unicode_sentence_object_NTM = NULL;
#line 80 "inform7/Chapter 10/Unicode Translations.w"
nonterminal *unicode_character_NTM = NULL;
#line 84 "inform7/Chapter 10/Unicode Translations.w"
nonterminal *unicode_character_name_NTM = NULL;
#line 335 "inform7/Chapter 11/Nametags.w"
nonterminal *translates_into_nl_sentence_subject_NTM = NULL;
#line 349 "inform7/Chapter 11/Instances.w"
nonterminal *instance_of_object_NTM = NULL;
#line 355 "inform7/Chapter 11/Instances.w"
nonterminal *instance_of_non_object_NTM = NULL;
#line 364 "inform7/Chapter 11/Instances.w"
nonterminal *instance_NTM = NULL;
#line 26 "inform7/Chapter 12/Architecture of the S-Parser.w"
nonterminal *s_plain_text_NTM = NULL;
#line 49 "inform7/Chapter 12/Architecture of the S-Parser.w"
nonterminal *s_plain_text_with_equals_NTM = NULL;
#line 21 "inform7/Chapter 12/Parse Literals.w"
nonterminal *s_literal_NTM = NULL;
#line 48 "inform7/Chapter 12/Parse Literals.w"
nonterminal *literal_NTM = NULL;
#line 60 "inform7/Chapter 12/Parse Literals.w"
nonterminal *literal_unit_notation_NTM = NULL;
#line 77 "inform7/Chapter 12/Parse Literals.w"
nonterminal *cardinal_number_in_words_NTM = NULL;
#line 95 "inform7/Chapter 12/Parse Literals.w"
nonterminal *ordinal_number_in_words_NTM = NULL;
#line 122 "inform7/Chapter 12/Parse Literals.w"
nonterminal *cardinal_number_NTM = NULL;
#line 131 "inform7/Chapter 12/Parse Literals.w"
nonterminal *ordinal_number_NTM = NULL;
#line 143 "inform7/Chapter 12/Parse Literals.w"
nonterminal *cardinal_number_unlimited_NTM = NULL;
#line 176 "inform7/Chapter 12/Parse Literals.w"
nonterminal *quoted_text_NTM = NULL;
#line 183 "inform7/Chapter 12/Parse Literals.w"
nonterminal *quoted_text_with_subs_NTM = NULL;
#line 190 "inform7/Chapter 12/Parse Literals.w"
nonterminal *quoted_text_without_subs_NTM = NULL;
#line 201 "inform7/Chapter 12/Parse Literals.w"
nonterminal *empty_text_NTM = NULL;
#line 212 "inform7/Chapter 12/Parse Literals.w"
nonterminal *response_letter_NTM = NULL;
#line 228 "inform7/Chapter 12/Parse Literals.w"
nonterminal *literal_truth_state_NTM = NULL;
#line 242 "inform7/Chapter 12/Parse Literals.w"
nonterminal *literal_real_number_NTM = NULL;
#line 249 "inform7/Chapter 12/Parse Literals.w"
nonterminal *literal_real_in_digits_NTM = NULL;
#line 18 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_constant_value_NTM = NULL;
#line 55 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_miscellaneous_proper_noun_NTM = NULL;
#line 85 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *spec_named_constant_NTM = NULL;
#line 102 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_rulebook_outcome_name_NTM = NULL;
#line 113 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_use_option_name_NTM = NULL;
#line 124 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_rule_name_NTM = NULL;
#line 141 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_table_column_name_NTM = NULL;
#line 154 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *property_name_as_noun_phrase_NTM = NULL;
#line 158 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_property_name_NTM = NULL;
#line 190 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_adjective_list_as_desc_NTM = NULL;
#line 250 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_adjective_list_NTM = NULL;
#line 255 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_adjective_list_unarticled_NTM = NULL;
#line 265 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_adjective_NTM = NULL;
#line 365 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_qualifiable_noun_NTM = NULL;
#line 369 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_qualifiable_common_noun_NTM = NULL;
#line 376 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_instance_name_NTM = NULL;
#line 390 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_applicable_adjective_list_NTM = NULL;
#line 440 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_description_NTM = NULL;
#line 444 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_description_uncomposite_NTM = NULL;
#line 448 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_description_uncalled_NTM = NULL;
#line 456 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_description_unspecified_NTM = NULL;
#line 460 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_common_description_unspecified_NTM = NULL;
#line 468 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_description_nounless_NTM = NULL;
#line 472 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_description_nounless_uncomposite_NTM = NULL;
#line 476 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_description_nounless_uncalled_NTM = NULL;
#line 484 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_description_nounless_unspecified_NTM = NULL;
#line 548 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_calling_name_NTM = NULL;
#line 565 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_specifier_NTM = NULL;
#line 582 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_specifying_noun_NTM = NULL;
#line 635 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_nonkind_type_NTM = NULL;
#line 639 "inform7/Chapter 12/Constants and Descriptions.w"
nonterminal *s_nonkind_type_unbracketed_NTM = NULL;
#line 61 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_type_expression_NTM = NULL;
#line 65 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_type_expression_unarticled_NTM = NULL;
#line 87 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_descriptive_type_expression_NTM = NULL;
#line 91 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_descriptive_type_expression_unarticled_NTM = NULL;
#line 108 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_variable_scope_NTM = NULL;
#line 136 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *if_let_equation_mode_NTM = NULL;
#line 146 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *if_pronoun_present_NTM = NULL;
#line 156 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *if_table_column_expected_NTM = NULL;
#line 162 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *if_property_name_expected_NTM = NULL;
#line 219 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_value_NTM = NULL;
#line 278 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_variable_NTM = NULL;
#line 284 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_nonglobal_variable_NTM = NULL;
#line 289 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_variable_as_value_NTM = NULL;
#line 295 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_local_variable_NTM = NULL;
#line 309 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_stacked_variable_NTM = NULL;
#line 327 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_global_variable_NTM = NULL;
#line 338 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *property_of_shape_NTM = NULL;
#line 350 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_value_phrase_non_of_NTM = NULL;
#line 364 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_value_phrase_NTM = NULL;
#line 387 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_table_reference_NTM = NULL;
#line 399 "inform7/Chapter 12/Type Expressions and Values.w"
nonterminal *s_action_pattern_as_value_NTM = NULL;
#line 56 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_sentence_NTM = NULL;
#line 71 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_existential_np_NTM = NULL;
#line 74 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_existential_verb_tail_NTM = NULL;
#line 119 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_general_verb_tail_NTM = NULL;
#line 137 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_universal_relation_term_NTM = NULL;
#line 155 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_np_with_relative_clause_NTM = NULL;
#line 159 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_implied_relative_verb_tail_NTM = NULL;
#line 163 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_relative_verb_tail_NTM = NULL;
#line 272 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_purely_physical_description_NTM = NULL;
#line 282 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *if_forced_physical_NTM = NULL;
#line 293 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_noun_phrase_NTM = NULL;
#line 298 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_noun_phrase_nounless_NTM = NULL;
#line 307 "inform7/Chapter 12/Verbal and Relative Clauses.w"
nonterminal *s_descriptive_np_NTM = NULL;
#line 39 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_condition_NTM = NULL;
#line 48 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_condition_pure_NTM = NULL;
#line 70 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_condition_with_chronology_NTM = NULL;
#line 115 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_condition_atomic_NTM = NULL;
#line 135 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_nonexistential_phrase_to_decide_NTM = NULL;
#line 140 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_existential_phrase_to_decide_NTM = NULL;
#line 145 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *existential_verb_phrase_NTM = NULL;
#line 148 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_phrase_to_decide_NTM = NULL;
#line 158 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_phrase_option_in_use_NTM = NULL;
#line 176 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_action_pattern_as_condition_NTM = NULL;
#line 179 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_action_pattern_as_negated_condition_NTM = NULL;
#line 185 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_past_action_pattern_as_condition_NTM = NULL;
#line 188 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_past_action_pattern_as_negated_condition_NTM = NULL;
#line 226 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_command_NTM = NULL;
#line 279 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_command_phrase_NTM = NULL;
#line 284 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_command_phrase_inner_NTM = NULL;
#line 292 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_to_phrase_NTM = NULL;
#line 302 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_say_phrase_NTM = NULL;
#line 313 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_say_term_NTM = NULL;
#line 317 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_text_substitution_NTM = NULL;
#line 356 "inform7/Chapter 12/Conditions and Phrases.w"
nonterminal *s_unpacked_text_with_substitutions_NTM = NULL;
#line 631 "inform7/Chapter 15/Kinds.w"
nonterminal *notable_linguistic_kinds_NTM = NULL;
#line 58 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *if_parsing_phrase_tokens_NTM = NULL;
#line 68 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *spec_phrase_token_type_NTM = NULL;
#line 82 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_kind_for_template_NTM = NULL;
#line 95 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *spec_kind_as_name_token_NTM = NULL;
#line 114 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_kind_as_name_token_NTM = NULL;
#line 121 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_kind_abbreviating_NTM = NULL;
#line 129 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_kind_NTM = NULL;
#line 140 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_kind_articled_NTM = NULL;
#line 148 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_variable_definition_NTM = NULL;
#line 159 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_base_kind_NTM = NULL;
#line 195 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_irregular_kind_construction_NTM = NULL;
#line 210 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_kind_construction_NTM = NULL;
#line 274 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_single_material_NTM = NULL;
#line 279 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_optional_material_NTM = NULL;
#line 286 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_tupled_material_NTM = NULL;
#line 291 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_tuple_list_NTM = NULL;
#line 376 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_kind_of_kind_NTM = NULL;
#line 422 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_kind_variable_NTM = NULL;
#line 436 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_formal_kind_variable_NTM = NULL;
#line 447 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_formal_kind_variable_singular_NTM = NULL;
#line 459 "inform7/Chapter 15/Describing Kinds.w"
nonterminal *k_kind_variable_texts_NTM = NULL;
#line 217 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_value_NTM = NULL;
#line 224 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_condition_NTM = NULL;
#line 231 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_command_NTM = NULL;
#line 238 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_type_expression_NTM = NULL;
#line 245 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_descriptive_type_expression_NTM = NULL;
#line 257 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_type_expression_or_value_NTM = NULL;
#line 265 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_global_variable_NTM = NULL;
#line 279 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_kind_NTM = NULL;
#line 293 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_description_NTM = NULL;
#line 299 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_instance_NTM = NULL;
#line 305 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_table_name_NTM = NULL;
#line 313 "inform7/Chapter 16/Text to Specifications.w"
nonterminal *spec_stored_action_NTM = NULL;
#line 67 "inform7/Chapter 16/STORAGE Specifications.w"
nonterminal *storage_nonkind_types_NTM = NULL;
#line 158 "inform7/Chapter 16/CONDITION Specifications.w"
nonterminal *condition_nonkind_types_NTM = NULL;
#line 68 "inform7/Chapter 16/COMMAND Specifications.w"
nonterminal *command_phrase_nonkind_types_NTM = NULL;
#line 629 "inform7/Chapter 16/Type Checking.w"
nonterminal *structural_phrase_problem_diagnosis_NTM = NULL;
#line 741 "inform7/Chapter 16/Type Checking.w"
nonterminal *unknown_text_shape_NTM = NULL;
#line 746 "inform7/Chapter 16/Type Checking.w"
nonterminal *unknown_text_substitution_problem_diagnosis_NTM = NULL;
#line 869 "inform7/Chapter 16/Type Checking.w"
nonterminal *unknown_value_problem_diagnosis_NTM = NULL;
#line 876 "inform7/Chapter 16/Type Checking.w"
nonterminal *unknown_use_option_diagnosis_NTM = NULL;
#line 880 "inform7/Chapter 16/Type Checking.w"
nonterminal *unknown_activity_diagnosis_NTM = NULL;
#line 3245 "inform7/Chapter 16/Type Checking.w"
nonterminal *failed_text_substitution_diagnosis_NTM = NULL;
#line 3359 "inform7/Chapter 16/Type Checking.w"
nonterminal *condition_problem_diagnosis_NTM = NULL;
#line 3363 "inform7/Chapter 16/Type Checking.w"
nonterminal *condition_problem_part_tail_NTM = NULL;
#line 3367 "inform7/Chapter 16/Type Checking.w"
nonterminal *condition_problem_part_NTM = NULL;
#line 230 "inform7/Chapter 17/Properties.w"
nonterminal *notable_properties_NTM = NULL;
#line 271 "inform7/Chapter 17/Properties.w"
nonterminal *property_name_construction_NTM = NULL;
#line 313 "inform7/Chapter 17/Properties.w"
nonterminal *property_name_NTM = NULL;
#line 329 "inform7/Chapter 17/Properties.w"
nonterminal *either_or_property_name_NTM = NULL;
#line 343 "inform7/Chapter 17/Properties.w"
nonterminal *value_property_name_NTM = NULL;
#line 361 "inform7/Chapter 17/Properties.w"
nonterminal *property_name_v_NTM = NULL;
#line 379 "inform7/Chapter 17/Properties.w"
nonterminal *name_looking_like_property_test_NTM = NULL;
#line 386 "inform7/Chapter 17/Properties.w"
nonterminal *ambiguous_property_name_NTM = NULL;
#line 232 "inform7/Chapter 17/Measurement Adjectives.w"
nonterminal *measurement_adjective_definition_NTM = NULL;
#line 237 "inform7/Chapter 17/Measurement Adjectives.w"
nonterminal *measurement_range_NTM = NULL;
#line 79 "inform7/Chapter 17/Value-Property Relations.w"
nonterminal *relation_property_name_NTM = NULL;
#line 50 "inform7/Chapter 18/The Naming Thicket.w"
nonterminal *notable_naming_properties_NTM = NULL;
#line 237 "inform7/Chapter 19/Spatial Model.w"
nonterminal *notable_spatial_kinds_NTM = NULL;
#line 335 "inform7/Chapter 19/Spatial Model.w"
nonterminal *notable_spatial_properties_NTM = NULL;
#line 409 "inform7/Chapter 19/Spatial Model.w"
nonterminal *spatial_specifying_nouns_NTM = NULL;
#line 454 "inform7/Chapter 19/Spatial Model.w"
nonterminal *notable_spatial_noun_phrases_NTM = NULL;
#line 52 "inform7/Chapter 19/The Player.w"
nonterminal *notable_player_instances_NTM = NULL;
#line 93 "inform7/Chapter 19/The Player.w"
nonterminal *notable_player_variables_NTM = NULL;
#line 246 "inform7/Chapter 19/The Player.w"
nonterminal *implicit_player_relationship_NTM = NULL;
#line 42 "inform7/Chapter 19/Backdrops.w"
nonterminal *notable_backdrops_kinds_NTM = NULL;
#line 70 "inform7/Chapter 19/Backdrops.w"
nonterminal *notable_backdrops_properties_NTM = NULL;
#line 178 "inform7/Chapter 19/Backdrops.w"
nonterminal *notable_backdrops_noun_phrases_NTM = NULL;
#line 71 "inform7/Chapter 19/Regions.w"
nonterminal *notable_regions_kinds_NTM = NULL;
#line 139 "inform7/Chapter 19/Regions.w"
nonterminal *notable_regions_properties_NTM = NULL;
#line 171 "inform7/Chapter 19/The Map.w"
nonterminal *notable_map_kinds_NTM = NULL;
#line 256 "inform7/Chapter 19/The Map.w"
nonterminal *notable_map_directions_NTM = NULL;
#line 427 "inform7/Chapter 19/The Map.w"
nonterminal *notable_map_properties_NTM = NULL;
#line 508 "inform7/Chapter 19/The Map.w"
nonterminal *notable_map_noun_phrases_NTM = NULL;
#line 91 "inform7/Chapter 19/Map Connection Relations.w"
nonterminal *mapping_relation_construction_NTM = NULL;
#line 94 "inform7/Chapter 19/Map Connection Relations.w"
nonterminal *mapping_preposition_construction_NTM = NULL;
#line 103 "inform7/Chapter 19/Map Connection Relations.w"
nonterminal *notable_directions_NTM = NULL;
#line 999 "inform7/Chapter 19/HTML Map.w"
nonterminal *map_name_abbreviation_omission_words_NTM = NULL;
#line 303 "inform7/Chapter 19/EPS Map.w"
nonterminal *direction_name_NTM = NULL;
#line 315 "inform7/Chapter 19/EPS Map.w"
nonterminal *index_map_sentence_subject_NTM = NULL;
#line 327 "inform7/Chapter 19/EPS Map.w"
nonterminal *map_positioning_NTM = NULL;
#line 387 "inform7/Chapter 19/EPS Map.w"
nonterminal *map_setting_NTM = NULL;
#line 392 "inform7/Chapter 19/EPS Map.w"
nonterminal *map_setting_scope_NTM = NULL;
#line 396 "inform7/Chapter 19/EPS Map.w"
nonterminal *map_setting_scope_unarticled_NTM = NULL;
#line 410 "inform7/Chapter 19/EPS Map.w"
nonterminal *map_parameter_NTM = NULL;
#line 439 "inform7/Chapter 19/EPS Map.w"
nonterminal *map_setting_value_NTM = NULL;
#line 446 "inform7/Chapter 19/EPS Map.w"
nonterminal *map_setting_boolean_NTM = NULL;
#line 456 "inform7/Chapter 19/EPS Map.w"
nonterminal *map_offset_NTM = NULL;
#line 466 "inform7/Chapter 19/EPS Map.w"
nonterminal *map_rubric_NTM = NULL;
#line 121 "inform7/Chapter 19/Scenes.w"
nonterminal *notable_scene_properties_NTM = NULL;
#line 179 "inform7/Chapter 19/Scenes.w"
nonterminal *notable_scenes_NTM = NULL;
#line 342 "inform7/Chapter 19/Scenes.w"
nonterminal *scene_ends_sentence_subject_NTM = NULL;
#line 359 "inform7/Chapter 19/Scenes.w"
nonterminal *scene_ends_sentence_adverb_NTM = NULL;
#line 367 "inform7/Chapter 19/Scenes.w"
nonterminal *scene_ends_sentence_object_NTM = NULL;
#line 411 "inform7/Chapter 19/Scenes.w"
nonterminal *scene_name_NTM = NULL;
#line 415 "inform7/Chapter 19/Scenes.w"
nonterminal *scene_name_unarticled_NTM = NULL;
#line 431 "inform7/Chapter 19/Scenes.w"
nonterminal *scene_end_name_NTM = NULL;
#line 437 "inform7/Chapter 19/Scenes.w"
nonterminal *scene_end_name_creating_NTM = NULL;
#line 864 "inform7/Chapter 19/Scenes.w"
nonterminal *spec_scene_description_NTM = NULL;
#line 62 "inform7/Chapter 20/Nonlocal Variables.w"
nonterminal *notable_variables_NTM = NULL;
#line 629 "inform7/Chapter 20/Nonlocal Variables.w"
nonterminal *value_understood_variable_name_NTM = NULL;
#line 52 "inform7/Chapter 20/Bibliographic Data.w"
nonterminal *notable_bibliographic_variables_NTM = NULL;
#line 92 "inform7/Chapter 20/Bibliographic Data.w"
nonterminal *titling_line_NTM = NULL;
#line 96 "inform7/Chapter 20/Bibliographic Data.w"
nonterminal *plain_titling_line_NTM = NULL;
#line 214 "inform7/Chapter 20/Bibliographic Data.w"
nonterminal *episode_sentence_object_NTM = NULL;
#line 65 "inform7/Chapter 20/Release Instructions.w"
nonterminal *release_sentence_object_NTM = NULL;
#line 103 "inform7/Chapter 20/Release Instructions.w"
nonterminal *privacy_indicator_NTM = NULL;
#line 107 "inform7/Chapter 20/Release Instructions.w"
nonterminal *exposed_innards_NTM = NULL;
#line 60 "inform7/Chapter 20/List Constants.w"
nonterminal *literal_list_NTM = NULL;
#line 64 "inform7/Chapter 20/List Constants.w"
nonterminal *literal_list_contents_NTM = NULL;
#line 68 "inform7/Chapter 20/List Constants.w"
nonterminal *literal_list_entry_NTM = NULL;
#line 223 "inform7/Chapter 20/Table Columns.w"
nonterminal *table_column_heading_NTM = NULL;
#line 230 "inform7/Chapter 20/Table Columns.w"
nonterminal *table_column_heading_unbracketed_NTM = NULL;
#line 272 "inform7/Chapter 20/Table Columns.w"
nonterminal *table_column_name_construction_NTM = NULL;
#line 249 "inform7/Chapter 20/Tables.w"
nonterminal *table_header_NTM = NULL;
#line 255 "inform7/Chapter 20/Tables.w"
nonterminal *table_new_name_NTM = NULL;
#line 277 "inform7/Chapter 20/Tables.w"
nonterminal *table_names_construction_NTM = NULL;
#line 287 "inform7/Chapter 20/Tables.w"
nonterminal *table_footer_NTM = NULL;
#line 862 "inform7/Chapter 20/Tables.w"
nonterminal *table_cell_NTM = NULL;
#line 871 "inform7/Chapter 20/Tables.w"
nonterminal *table_cell_blank_NTM = NULL;
#line 874 "inform7/Chapter 20/Tables.w"
nonterminal *table_cell_value_NTM = NULL;
#line 880 "inform7/Chapter 20/Tables.w"
nonterminal *list_of_double_quotes_NTM = NULL;
#line 308 "inform7/Chapter 20/Runtime Support for Tables.w"
nonterminal *rankings_table_name_NTM = NULL;
#line 31 "inform7/Chapter 20/Tables of Definitions.w"
nonterminal *defined_by_sentence_subject_NTM = NULL;
#line 64 "inform7/Chapter 20/Tables of Definitions.w"
nonterminal *defined_by_sentence_object_NTM = NULL;
#line 368 "inform7/Chapter 20/Tables of Definitions.w"
nonterminal *unfortunate_table_column_property_NTM = NULL;
#line 142 "inform7/Chapter 21/Equations.w"
nonterminal *equation_name_NTM = NULL;
#line 239 "inform7/Chapter 21/Equations.w"
nonterminal *equation_names_construction_NTM = NULL;
#line 322 "inform7/Chapter 21/Equations.w"
nonterminal *equation_where_NTM = NULL;
#line 381 "inform7/Chapter 21/Equations.w"
nonterminal *equation_where_list_NTM = NULL;
#line 386 "inform7/Chapter 21/Equations.w"
nonterminal *equation_where_tail_NTM = NULL;
#line 390 "inform7/Chapter 21/Equations.w"
nonterminal *equation_where_setting_entry_NTM = NULL;
#line 393 "inform7/Chapter 21/Equations.w"
nonterminal *equation_where_setting_NTM = NULL;
#line 402 "inform7/Chapter 21/Equations.w"
nonterminal *equation_symbol_NTM = NULL;
#line 640 "inform7/Chapter 21/Equations.w"
nonterminal *valid_equation_symbol_NTM = NULL;
#line 110 "inform7/Chapter 21/Inform 6 Inclusions.w"
nonterminal *inform6_inclusion_location_NTM = NULL;
#line 118 "inform7/Chapter 21/Inform 6 Inclusions.w"
nonterminal *inclusion_side_NTM = NULL;
#line 288 "inform7/Chapter 21/Inform 6 Inclusions.w"
nonterminal *use_translates_as_sentence_object_NTM = NULL;
#line 323 "inform7/Chapter 21/Inform 6 Inclusions.w"
nonterminal *use_sentence_object_NTM = NULL;
#line 334 "inform7/Chapter 21/Inform 6 Inclusions.w"
nonterminal *notable_use_option_name_NTM = NULL;
#line 460 "inform7/Chapter 21/Inform 6 Inclusions.w"
nonterminal *immediate_use_NTM = NULL;
#line 465 "inform7/Chapter 21/Inform 6 Inclusions.w"
nonterminal *immediate_use_tail_NTM = NULL;
#line 469 "inform7/Chapter 21/Inform 6 Inclusions.w"
nonterminal *immediate_use_entry_NTM = NULL;
#line 307 "inform7/Chapter 22/Phrases.w"
nonterminal *inline_phrase_definition_NTM = NULL;
#line 132 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *rule_preamble_NTM = NULL;
#line 186 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *now_phrase_preamble_NTM = NULL;
#line 196 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *rule_preamble_fine_NTM = NULL;
#line 200 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *rule_preamble_finer_NTM = NULL;
#line 205 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *rulebook_stem_embellished_NTM = NULL;
#line 420 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *unrecognised_rule_stem_diagnosis_NTM = NULL;
#line 508 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *when_while_clause_NTM = NULL;
#line 897 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *parametric_problem_diagnosis_NTM = NULL;
#line 924 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *action_problem_diagnosis_NTM = NULL;
#line 962 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *action_when_diagnosis_NTM = NULL;
#line 972 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *anl_diagnosis_NTM = NULL;
#line 976 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *anl_inner_diagnosis_NTM = NULL;
#line 980 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *anl_tail_diagnosis_NTM = NULL;
#line 984 "inform7/Chapter 22/Phrase Usage.w"
nonterminal *anl_entry_diagnosis_NTM = NULL;
#line 430 "inform7/Chapter 22/Describing Phrase Type Data.w"
nonterminal *phrase_preamble_NTM = NULL;
#line 435 "inform7/Chapter 22/Describing Phrase Type Data.w"
nonterminal *to_preamble_NTM = NULL;
#line 451 "inform7/Chapter 22/Describing Phrase Type Data.w"
nonterminal *say_preamble_NTM = NULL;
#line 476 "inform7/Chapter 22/Describing Phrase Type Data.w"
nonterminal *to_return_data_NTM = NULL;
#line 485 "inform7/Chapter 22/Describing Phrase Type Data.w"
nonterminal *return_kind_NTM = NULL;
#line 599 "inform7/Chapter 22/Describing Phrase Type Data.w"
nonterminal *phrase_definition_word_or_token_NTM = NULL;
#line 610 "inform7/Chapter 22/Describing Phrase Type Data.w"
nonterminal *phrase_token_declaration_NTM = NULL;
#line 137 "inform7/Chapter 22/Phrase Options.w"
nonterminal *phrase_option_declaration_list_NTM = NULL;
#line 142 "inform7/Chapter 22/Phrase Options.w"
nonterminal *phrase_option_declaration_tail_NTM = NULL;
#line 148 "inform7/Chapter 22/Phrase Options.w"
nonterminal *phrase_option_declaration_setting_entry_NTM = NULL;
#line 255 "inform7/Chapter 22/Phrase Options.w"
nonterminal *phrase_option_list_NTM = NULL;
#line 260 "inform7/Chapter 22/Phrase Options.w"
nonterminal *phrase_option_tail_NTM = NULL;
#line 264 "inform7/Chapter 22/Phrase Options.w"
nonterminal *phrase_option_setting_entry_NTM = NULL;
#line 296 "inform7/Chapter 22/Phrase Options.w"
nonterminal *phrase_option_NTM = NULL;
#line 632 "inform7/Chapter 22/Local Variables.w"
nonterminal *new_called_name_NTM = NULL;
#line 637 "inform7/Chapter 22/Local Variables.w"
nonterminal *new_called_name_unarticled_NTM = NULL;
#line 642 "inform7/Chapter 22/Local Variables.w"
nonterminal *existing_local_name_NTM = NULL;
#line 16 "inform7/Chapter 22/Parse Invocations.w"
nonterminal *end_phrase_construction_NTM = NULL;
#line 373 "inform7/Chapter 22/Compile Invocations Inline.w"
nonterminal *inline_substitution_NTM = NULL;
#line 382 "inform7/Chapter 22/Compile Invocations Inline.w"
nonterminal *name_local_to_inline_stack_frame_NTM = NULL;
#line 135 "inform7/Chapter 22/Phrasebook Index.w"
nonterminal *heading_with_parenthesis_NTM = NULL;
#line 140 "inform7/Chapter 22/Phrasebook Index.w"
nonterminal *heading_name_hyphenated_NTM = NULL;
#line 52 "inform7/Chapter 22/Adjectival Definitions.w"
nonterminal *definition_header_NTM = NULL;
#line 85 "inform7/Chapter 22/Adjectival Definitions.w"
nonterminal *adjective_definition_NTM = NULL;
#line 90 "inform7/Chapter 22/Adjectival Definitions.w"
nonterminal *adjective_domain_NTM = NULL;
#line 95 "inform7/Chapter 22/Adjectival Definitions.w"
nonterminal *adjective_wording_NTM = NULL;
#line 343 "inform7/Chapter 22/Adjectival Definitions.w"
nonterminal *inform6_routine_adjective_definition_NTM = NULL;
#line 409 "inform7/Chapter 22/Adjectival Definitions.w"
nonterminal *inform6_condition_adjective_definition_NTM = NULL;
#line 160 "inform7/Chapter 23/Rulebooks.w"
nonterminal *new_rulebook_name_NTM = NULL;
#line 209 "inform7/Chapter 23/Rulebooks.w"
nonterminal *rulebook_name_construction_NTM = NULL;
#line 407 "inform7/Chapter 23/Rulebooks.w"
nonterminal *rulebook_variable_name_NTM = NULL;
#line 593 "inform7/Chapter 23/Rulebooks.w"
nonterminal *rulebook_stem_NTM = NULL;
#line 621 "inform7/Chapter 23/Rulebooks.w"
nonterminal *rulebook_stem_inner_NTM = NULL;
#line 626 "inform7/Chapter 23/Rulebooks.w"
nonterminal *rulebook_stem_inner_unarticled_NTM = NULL;
#line 633 "inform7/Chapter 23/Rulebooks.w"
nonterminal *rulebook_stem_name_NTM = NULL;
#line 863 "inform7/Chapter 23/Rulebooks.w"
nonterminal *rulebook_property_NTM = NULL;
#line 110 "inform7/Chapter 23/Focus and Outcome.w"
nonterminal *rulebook_default_outcome_NTM = NULL;
#line 114 "inform7/Chapter 23/Focus and Outcome.w"
nonterminal *rule_outcome_NTM = NULL;
#line 153 "inform7/Chapter 23/Focus and Outcome.w"
nonterminal *rulebook_outcome_list_NTM = NULL;
#line 158 "inform7/Chapter 23/Focus and Outcome.w"
nonterminal *rulebook_outcome_tail_NTM = NULL;
#line 162 "inform7/Chapter 23/Focus and Outcome.w"
nonterminal *rulebook_outcome_setting_entry_NTM = NULL;
#line 165 "inform7/Chapter 23/Focus and Outcome.w"
nonterminal *form_of_named_rule_outcome_NTM = NULL;
#line 28 "inform7/Chapter 23/Rule Placement Sentences.w"
nonterminal *rulebook_name_NTM = NULL;
#line 40 "inform7/Chapter 23/Rule Placement Sentences.w"
nonterminal *rule_name_NTM = NULL;
#line 63 "inform7/Chapter 23/Rule Placement Sentences.w"
nonterminal *substitutes_for_sentence_subject_NTM = NULL;
#line 67 "inform7/Chapter 23/Rule Placement Sentences.w"
nonterminal *substitutes_for_sentence_object_NTM = NULL;
#line 108 "inform7/Chapter 23/Rule Placement Sentences.w"
nonterminal *does_nothing_sentence_subject_NTM = NULL;
#line 143 "inform7/Chapter 23/Rule Placement Sentences.w"
nonterminal *listed_in_sentence_subject_NTM = NULL;
#line 150 "inform7/Chapter 23/Rule Placement Sentences.w"
nonterminal *listed_in_sentence_object_NTM = NULL;
#line 163 "inform7/Chapter 23/Rule Placement Sentences.w"
nonterminal *offset_rule_NTM = NULL;
#line 167 "inform7/Chapter 23/Rule Placement Sentences.w"
nonterminal *destination_rulebook_NTM = NULL;
#line 187 "inform7/Chapter 24/Chronology.w"
nonterminal *historical_reference_possible_NTM = NULL;
#line 193 "inform7/Chapter 24/Chronology.w"
nonterminal *historical_reference_NTM = NULL;
#line 197 "inform7/Chapter 24/Chronology.w"
nonterminal *repetition_specification_NTM = NULL;
#line 207 "inform7/Chapter 24/Chronology.w"
nonterminal *repetitions_NTM = NULL;
#line 211 "inform7/Chapter 24/Chronology.w"
nonterminal *iteration_repetitions_NTM = NULL;
#line 218 "inform7/Chapter 24/Chronology.w"
nonterminal *turn_repetitions_NTM = NULL;
#line 222 "inform7/Chapter 24/Chronology.w"
nonterminal *rep_number_NTM = NULL;
#line 245 "inform7/Chapter 24/Actions.w"
nonterminal *notable_actions_NTM = NULL;
#line 252 "inform7/Chapter 24/Actions.w"
nonterminal *action_name_construction_NTM = NULL;
#line 353 "inform7/Chapter 24/Actions.w"
nonterminal *action_pronoun_NTM = NULL;
#line 380 "inform7/Chapter 24/Actions.w"
nonterminal *action_name_NTM = NULL;
#line 408 "inform7/Chapter 24/Actions.w"
nonterminal *action_optional_trailing_prepositions_NTM = NULL;
#line 520 "inform7/Chapter 24/Actions.w"
nonterminal *action_variable_NTM = NULL;
#line 528 "inform7/Chapter 24/Actions.w"
nonterminal *action_variable_name_NTM = NULL;
#line 730 "inform7/Chapter 24/Actions.w"
nonterminal *action_sentence_subject_NTM = NULL;
#line 758 "inform7/Chapter 24/Actions.w"
nonterminal *action_clause_NTM = NULL;
#line 765 "inform7/Chapter 24/Actions.w"
nonterminal *action_applications_NTM = NULL;
#line 776 "inform7/Chapter 24/Actions.w"
nonterminal *act_req_NTM = NULL;
#line 780 "inform7/Chapter 24/Actions.w"
nonterminal *action_access_NTM = NULL;
#line 788 "inform7/Chapter 24/Actions.w"
nonterminal *action_sentence_object_NTM = NULL;
#line 792 "inform7/Chapter 24/Actions.w"
nonterminal *action_clauses_NTM = NULL;
#line 797 "inform7/Chapter 24/Actions.w"
nonterminal *action_clause_terminated_NTM = NULL;
#line 105 "inform7/Chapter 24/Action Name Lists.w"
nonterminal *action_list_NTM = NULL;
#line 113 "inform7/Chapter 24/Action Name Lists.w"
nonterminal *anl_excluded_NTM = NULL;
#line 137 "inform7/Chapter 24/Action Name Lists.w"
nonterminal *anl_to_tail_NTM = NULL;
#line 141 "inform7/Chapter 24/Action Name Lists.w"
nonterminal *anl_operand_NTM = NULL;
#line 144 "inform7/Chapter 24/Action Name Lists.w"
nonterminal *anl_in_tail_NTM = NULL;
#line 176 "inform7/Chapter 24/Action Name Lists.w"
nonterminal *anl_NTM = NULL;
#line 180 "inform7/Chapter 24/Action Name Lists.w"
nonterminal *anl_tail_NTM = NULL;
#line 195 "inform7/Chapter 24/Action Name Lists.w"
nonterminal *anl_entry_NTM = NULL;
#line 593 "inform7/Chapter 24/Action Patterns.w"
nonterminal *action_pattern_NTM = NULL;
#line 607 "inform7/Chapter 24/Action Patterns.w"
nonterminal *we_are_action_pattern_NTM = NULL;
#line 618 "inform7/Chapter 24/Action Patterns.w"
nonterminal *action_pattern_negated_NTM = NULL;
#line 629 "inform7/Chapter 24/Action Patterns.w"
nonterminal *action_pattern_past_NTM = NULL;
#line 637 "inform7/Chapter 24/Action Patterns.w"
nonterminal *action_pattern_past_negated_NTM = NULL;
#line 658 "inform7/Chapter 24/Action Patterns.w"
nonterminal *action_pattern_core_actor_NTM = NULL;
#line 677 "inform7/Chapter 24/Action Patterns.w"
nonterminal *actor_description_NTM = NULL;
#line 741 "inform7/Chapter 24/Action Patterns.w"
nonterminal *action_pattern_core_NTM = NULL;
#line 748 "inform7/Chapter 24/Action Patterns.w"
nonterminal *action_pattern_past_core_NTM = NULL;
#line 765 "inform7/Chapter 24/Action Patterns.w"
nonterminal *action_pronominal_NTM = NULL;
#line 814 "inform7/Chapter 24/Action Patterns.w"
nonterminal *ap_common_core_NTM = NULL;
#line 825 "inform7/Chapter 24/Action Patterns.w"
nonterminal *condition_in_ap_NTM = NULL;
#line 847 "inform7/Chapter 24/Action Patterns.w"
nonterminal *ap_common_core_inner_NTM = NULL;
#line 862 "inform7/Chapter 24/Action Patterns.w"
nonterminal *ap_common_core_inner_inner_NTM = NULL;
#line 868 "inform7/Chapter 24/Action Patterns.w"
nonterminal *named_action_pattern_NTM = NULL;
#line 915 "inform7/Chapter 24/Action Patterns.w"
nonterminal *ap_common_core_inner_inner_inner_NTM = NULL;
#line 939 "inform7/Chapter 24/Action Patterns.w"
nonterminal *action_operand_NTM = NULL;
#line 944 "inform7/Chapter 24/Action Patterns.w"
nonterminal *going_action_irregular_operand_NTM = NULL;
#line 948 "inform7/Chapter 24/Action Patterns.w"
nonterminal *understanding_action_irregular_operand_NTM = NULL;
#line 956 "inform7/Chapter 24/Action Patterns.w"
nonterminal *action_parameter_NTM = NULL;
#line 965 "inform7/Chapter 24/Action Patterns.w"
nonterminal *spec_local_variable_NTM = NULL;
#line 117 "inform7/Chapter 24/Activities.w"
nonterminal *activity_sentence_subject_NTM = NULL;
#line 122 "inform7/Chapter 24/Activities.w"
nonterminal *activity_noted_NTM = NULL;
#line 127 "inform7/Chapter 24/Activities.w"
nonterminal *activity_new_name_NTM = NULL;
#line 136 "inform7/Chapter 24/Activities.w"
nonterminal *activity_name_construction_NTM = NULL;
#line 259 "inform7/Chapter 24/Activities.w"
nonterminal *activity_variable_name_NTM = NULL;
#line 451 "inform7/Chapter 24/Activities.w"
nonterminal *run_time_context_NTM = NULL;
#line 455 "inform7/Chapter 24/Activities.w"
nonterminal *activity_list_unnegated_NTM = NULL;
#line 460 "inform7/Chapter 24/Activities.w"
nonterminal *activity_tail_NTM = NULL;
#line 464 "inform7/Chapter 24/Activities.w"
nonterminal *activity_list_entry_NTM = NULL;
#line 480 "inform7/Chapter 24/Activities.w"
nonterminal *activity_operand_NTM = NULL;
#line 551 "inform7/Chapter 24/Activities.w"
nonterminal *activity_name_NTM = NULL;
#line 578 "inform7/Chapter 24/Activities.w"
nonterminal *if_parsing_al_conditions_NTM = NULL;
#line 138 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_sentence_subject_NTM = NULL;
#line 160 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_regular_list_NTM = NULL;
#line 165 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_regular_tail_NTM = NULL;
#line 169 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_regular_entry_NTM = NULL;
#line 176 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_property_list_NTM = NULL;
#line 181 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_property_tail_NTM = NULL;
#line 185 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_property_entry_NTM = NULL;
#line 251 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_sentence_object_NTM = NULL;
#line 255 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_sentence_object_uncond_NTM = NULL;
#line 260 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_sentence_object_tail_NTM = NULL;
#line 264 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_sentence_entry_NTM = NULL;
#line 293 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_as_this_NTM = NULL;
#line 304 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_ref_NTM = NULL;
#line 376 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_command_sentence_object_NTM = NULL;
#line 405 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_property_sentence_object_NTM = NULL;
#line 409 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_property_sentence_object_unconditional_NTM = NULL;
#line 414 "inform7/Chapter 25/Traverse for Grammar.w"
nonterminal *understand_property_reference_NTM = NULL;
#line 97 "inform7/Chapter 25/Grammar Properties.w"
nonterminal *notable_parsing_variables_NTM = NULL;
#line 187 "inform7/Chapter 25/Grammar Lines.w"
nonterminal *understand_condition_NTM = NULL;
#line 212 "inform7/Chapter 25/Grammar Lines.w"
nonterminal *spec_non_action_condition_NTM = NULL;
#line 62 "inform7/Chapter 25/Grammar Tokens.w"
nonterminal *grammar_token_breaking_NTM = NULL;
#line 210 "inform7/Chapter 25/Grammar Tokens.w"
nonterminal *grammar_token_NTM = NULL;
#line 228 "inform7/Chapter 25/Grammar Tokens.w"
nonterminal *standard_grammar_token_NTM = NULL;
#line 245 "inform7/Chapter 25/Grammar Tokens.w"
nonterminal *named_grammar_token_NTM = NULL;
#line 78 "inform7/Chapter 25/Test Scripts.w"
nonterminal *test_sentence_subject_NTM = NULL;
#line 88 "inform7/Chapter 25/Test Scripts.w"
nonterminal *internal_test_case_name_NTM = NULL;
#line 112 "inform7/Chapter 25/Test Scripts.w"
nonterminal *test_sentence_object_NTM = NULL;
#line 117 "inform7/Chapter 25/Test Scripts.w"
nonterminal *test_case_circumstance_list_NTM = NULL;
#line 122 "inform7/Chapter 25/Test Scripts.w"
nonterminal *test_case_circumstance_NTM = NULL;
#line 105 "inform7/Chapter 26/Figures.w"
nonterminal *figure_sentence_object_NTM = NULL;
#line 109 "inform7/Chapter 26/Figures.w"
nonterminal *figure_source_NTM = NULL;
#line 129 "inform7/Chapter 26/Figures.w"
nonterminal *notable_figures_NTM = NULL;
#line 97 "inform7/Chapter 26/Sound Effects.w"
nonterminal *sound_sentence_object_NTM = NULL;
#line 101 "inform7/Chapter 26/Sound Effects.w"
nonterminal *sound_source_NTM = NULL;
#line 91 "inform7/Chapter 26/External Files.w"
nonterminal *external_file_sentence_subject_NTM = NULL;
#line 97 "inform7/Chapter 26/External Files.w"
nonterminal *external_file_name_NTM = NULL;
#line 101 "inform7/Chapter 26/External Files.w"
nonterminal *external_file_owner_NTM = NULL;
#line 127 "inform7/Chapter 26/External Files.w"
nonterminal *external_file_sentence_object_NTM = NULL;
#line 74 "inform7/Chapter 27/Plugins.w"
nonterminal *plugin_name_NTM = NULL;
#line 99 "inform7/Chapter 27/Plugins.w"
nonterminal *language_element_NTM = NULL;
#line 225 "inform7/Chapter 27/Plugins.w"
nonterminal *use_language_element_sentence_subject_NTM = NULL;
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 giving_parts_NTMV = 0;
int is_participle_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;
specification * specification_cond_NTMV = NULL;
int series_NTMV = 0;
int privacy_NTMV = 0;
int alttext_NTMV = 0;
int k1_NTMV = 0;
int k2_NTMV = 0;
int nameforms_NTMV = 0;
int each_NTMV = 0;
specification * specification_s_NTMV = NULL;
int inlinecode_NTMV = 0;
int event_time_NTMV = 0;
int written_NTMV = 0;
int named_NTMV = 0;
int inverted_NTMV = 0;
specification * specification_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 run_on_NTMV = 0;
int control_NTMV = 0;
int token_form_NTMV = 0;
int token_nameflag_NTMV = 0;
int opt_NTMV = 0;
local_variable * local_variable_var_NTMV = NULL;
int calling_NTMV = 0;
int antonym_NTMV = 0;
int place_NTMV = 0;
int len_NTMV = 0;
rulebook * rulebook_m_NTMV = NULL;
int from_NTMV = 0;
int unit_NTMV = 0;
int to_NTMV = 0;
int num_NTMV = 0;
kind * kind_op1_NTMV = NULL;
int ac1_NTMV = 0;
kind * kind_op2_NTMV = NULL;
int ac2_NTMV = 0;
int ds_NTMV = 0;
int future_NTMV = 0;
int any_NTMV = 0;
kind * kind_understood_NTMV = NULL;
grammar_verb * grammar_verb_named_NTMV = NULL;
int ownership_NTMV = 0;
void register_tangled_nonterminals(void);
#line 21 "inform7/Chapter 1/Basic Definitions.w"
#line 48 "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 fix_rng_at_start_of_play = FALSE; /* Compile I6 code which seeds the RNG */
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 = NULL; /* 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 62 "inform7/Chapter 1/Basic Definitions.w"
int no_deprecated_features = FALSE; /* forbid syntaxes marked as deprecated? */
#line 76 "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 199 "inform7/Chapter 1/Basic Definitions.w"
STREAM debug_log_file_struct; /* The actual debugging log file */
STREAM inform6_file_struct; /* The actual I6 code file */
STREAM problems_file_struct; /* The actual report of Problems file */
STREAM index_file_struct; /* The current index file being written */
STREAM telemetry_file_struct; /* The actual telemetry file (if created) */
STREAM *debug_log_file = &debug_log_file_struct; /* The actual debugging log file */
STREAM *inform6_file = &inform6_file_struct; /* The actual I6 code file */
STREAM *problems_file = &problems_file_struct; /* The actual report of Problems file */
STREAM *telemetry_file = &telemetry_file_struct; /* The actual debugging log file */
STREAM *dl = NULL; /* Current destination of debugging text */
STREAM *ifl = NULL; /* Current destination of index text */
STREAM *probl = NULL; /* Current destination of problem message 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 228 "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
#define PLATFORM_MACOSX /* the original home for NI, and still the default */
#endif
#endif
#endif
#ifndef CPU_WORDSIZE_MULTIPLIER
#define CPU_WORDSIZE_MULTIPLIER 1 /* the CPU word size is by default 32 bits */
#endif
#line 79 "inform7/Chapter 2/Memory.w"
#line 18 "inform7/Chapter 2/Single Integers.w"
#line 61 "inform7/Chapter 2/Streams.w"
#define WRITE(args...) stream_printf(OUT, args)
#define INDEX(args...) stream_printf(ifl, args)
#define STREAM_WRITE(stream, args...) stream_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 35 "inform7/Chapter 2/Inform 6 Labels.w"
#line 34 "inform7/Chapter 3/Index File Services.w"
#line 46 "inform7/Chapter 3/Index File Services.w"
#line 80 "inform7/Chapter 3/Index File Services.w"
#line 47 "inform7/Chapter 3/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 28 "inform7/Chapter 4/Debugging Log.w"
#define LOG(args...) dlprintf(args)
#define LOGIF(aspect, args...) { \
if (Log__Aspects__on(aspect##_DA)) dlprintf(args); \
}
#define LOG_INDENT STREAM_INDENT(dl)
#define LOG_OUTDENT STREAM_OUTDENT(dl)
#line 121 "inform7/Chapter 4/Debugging Log.w"
#line 189 "inform7/Chapter 4/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 51 "inform7/Chapter 5/Lexer.w"
source_location lexer_position;
#line 77 "inform7/Chapter 5/Lexer.w"
int lexer_wordcount; /* Number of words read in to arrays */
#line 212 "inform7/Chapter 5/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 5/Read Source Text.w"
source_file *primary_source_file = NULL; /* first to be opened */
#line 55 "inform7/Chapter 5/Vocabulary.w"
#line 32 "inform7/Chapter 5/Tries and Inflections.w"
#line 45 "inform7/Chapter 5/Tries and Inflections.w"
#line 22 "inform7/Chapter 5/Word Assemblages.w"
#line 29 "inform7/Chapter 5/Clusters.w"
#line 39 "inform7/Chapter 5/Clusters.w"
#line 53 "inform7/Chapter 5/Clusters.w"
#line 48 "inform7/Chapter 5/Natural Languages.w"
#line 53 "inform7/Chapter 5/Natural Languages.w"
natural_language *English_language = NULL; /* until created, early in run */
#line 58 "inform7/Chapter 5/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 88 "inform7/Chapter 5/Preform.w"
int language_definition_top = -1;
#line 94 "inform7/Chapter 5/Preform.w"
natural_language *language_being_read_by_Preform = NULL;
#line 185 "inform7/Chapter 5/Preform.w"
#line 198 "inform7/Chapter 5/Preform.w"
#line 260 "inform7/Chapter 5/Preform.w"
#line 320 "inform7/Chapter 5/Preform.w"
#line 325 "inform7/Chapter 5/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 334 "inform7/Chapter 5/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 368 "inform7/Chapter 5/Preform.w"
int no_req_bits = 0;
#line 60 "inform7/Chapter 5/Non-Parsing Preform.w"
#line 66 "inform7/Chapter 5/Non-Parsing Preform.w"
#line 70 "inform7/Chapter 5/Non-Parsing Preform.w"
verb_conjugation *to_be_conjugation = NULL;
#line 100 "inform7/Chapter 6/Parse Tree.w"
#line 112 "inform7/Chapter 6/Parse Tree.w"
#line 194 "inform7/Chapter 6/Parse Tree.w"
parse_node *tree_root = NULL;
parse_node *current_sentence = NULL;
int near_start_of_extension = 0;
#line 17 "inform7/Chapter 6/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 */
parse_node *first_extension_inclusion = NULL; /* presumably always the Standard Rules */
#line 51 "inform7/Chapter 6/Virtual Machines.w"
#line 67 "inform7/Chapter 6/Virtual Machines.w"
#line 74 "inform7/Chapter 6/Headings.w"
#line 81 "inform7/Chapter 6/Headings.w"
heading pseudo_heading; /* The entire source falls under this top-level heading */
#line 176 "inform7/Chapter 6/Headings.w"
#line 185 "inform7/Chapter 6/Headings.w"
#line 39 "inform7/Chapter 6/Rule Subtrees.w"
control_structure_phrase
*switch_CSP = NULL,
*if_CSP = NULL,
*repeat_CSP = NULL,
*while_CSP = NULL,
*otherwise_CSP = NULL,
*otherwise_if_CSP = NULL,
*default_case_CSP = NULL,
*case_CSP = NULL,
*lambda_CSP = NULL;
#line 87 "inform7/Chapter 6/Verify Parse Tree.w"
#line 93 "inform7/Chapter 6/Verify Parse Tree.w"
parse_tree_node_type parse_tree_node_types[];
#line 181 "inform7/Chapter 7/Extension Files.w"
extension_file *standard_rules_extension; /* the Standard Rules by Graham Nelson */
#line 34 "inform7/Chapter 7/Extension Identifiers.w"
#line 58 "inform7/Chapter 7/Extension Identifiers.w"
#line 35 "inform7/Chapter 7/Extension Census.w"
#line 38 "inform7/Chapter 7/Extension Dictionary.w"
extension_dictionary_entry *first_in_sorted_dictionary = NULL;
#line 60 "inform7/Chapter 7/Extension Dictionary.w"
#line 27 "inform7/Chapter 8/Traverse for Assertions.w"
int traverse; /* always 1 or 2 */
#line 53 "inform7/Chapter 8/Traverse for Assertions.w"
#line 59 "inform7/Chapter 8/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 47 "inform7/Chapter 8/Assemblies.w"
#line 59 "inform7/Chapter 8/Assemblies.w"
#line 70 "inform7/Chapter 8/Assemblies.w"
#line 30 "inform7/Chapter 8/Implications.w"
#line 38 "inform7/Chapter 8/Implications.w"
#line 62 "inform7/Chapter 9/Determiners and Quantifiers.w"
#line 66 "inform7/Chapter 9/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 9/Determiners and Quantifiers.w"
#line 145 "inform7/Chapter 9/Binary Predicates.w"
#line 249 "inform7/Chapter 9/Binary Predicates.w"
#line 30 "inform7/Chapter 9/Relations.w"
#line 11 "inform7/Chapter 9/The Universal Relation.w"
binary_predicate *R_universal = NULL;
binary_predicate *R_meaning = NULL;
#line 39 "inform7/Chapter 9/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" */
#line 70 "inform7/Chapter 9/Conjugation of Verbs.w"
#line 57 "inform7/Chapter 9/Adjectives.w"
#line 111 "inform7/Chapter 9/Adjectives.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 76 "inform7/Chapter 10/Excerpt Meanings.w"
#line 81 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning *meaning_of_player = NULL;
#line 53 "inform7/Chapter 11/Nametags.w"
#line 48 "inform7/Chapter 11/Instances.w"
#line 56 "inform7/Chapter 11/Instances.w"
#line 60 "inform7/Chapter 11/Instances.w"
instance *latest_instance = NULL;
#line 67 "inform7/Chapter 11/Instances.w"
int no_ggs_recorded = 0;
instance *grammatical_genders[NO_GRAMMATICAL_GENDERS];
#line 136 "inform7/Chapter 12/Meaning Lists.w"
int no_permanent_MLs = 0, no_ephemeral_MLs = 0, GAP_movements = 0;
#line 59 "inform7/Chapter 12/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 68 "inform7/Chapter 12/Parse Excerpts.w"
vocabulary_entry *word_to_suppress_in_phrases = NULL;
#line 18 "inform7/Chapter 12/Conditions and Phrases.w"
int last_parsed_phrase_was_if = FALSE;
int last_parsed_phrase_opened_a_block = FALSE;
#line 64 "inform7/Chapter 13/Terms.w"
#line 86 "inform7/Chapter 13/Terms.w"
#line 46 "inform7/Chapter 13/Atomic Propositions.w"
#line 34 "inform7/Chapter 13/Type Check Propositions.w"
#line 45 "inform7/Chapter 13/Type Check Propositions.w"
#line 11 "inform7/Chapter 14/The Equality Relation.w"
binary_predicate *R_equality = NULL;
#line 21 "inform7/Chapter 14/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 14/Assert Propositions.w"
int ptim_recursion_depth = 0; /* depth of recursion of |prop_true_in_model| */
#line 66 "inform7/Chapter 14/I6 Schemas.w"
#line 34 "inform7/Chapter 14/Compile Atoms.w"
#line 53 "inform7/Chapter 14/Compile Atoms.w"
int suppress_C14CantChangeKind = FALSE;
int suppress_C14ActionVarsPastTense = FALSE;
#line 44 "inform7/Chapter 14/Deciding to Defer.w"
#line 141 "inform7/Chapter 15/Kinds.w"
kind *K_value = NULL;
kind *K_word_value = NULL;
kind *K_pointer_value = NULL;
#line 153 "inform7/Chapter 15/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 179 "inform7/Chapter 15/Kinds.w"
kind *K_nil = NULL;
kind_constructor *CON_NIL = NULL;
kind_constructor *CON_TUPLE_ENTRY = NULL;
#line 191 "inform7/Chapter 15/Kinds.w"
kind_constructor *CON_INTERMEDIATE = NULL;
#line 202 "inform7/Chapter 15/Kinds.w"
kind_constructor *CON_KIND_VARIABLE = NULL;
#line 208 "inform7/Chapter 15/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 239 "inform7/Chapter 15/Kinds.w"
kind *K_rulebook_outcome = NULL;
kind *K_understanding = NULL;
#line 245 "inform7/Chapter 15/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;
#line 265 "inform7/Chapter 15/Kinds.w"
#line 269 "inform7/Chapter 15/Kinds.w"
int no_base_kinds_created = 0;
int no_intermediate_kinds_created = 0;
int no_constructed_kinds_created = 0;
#line 72 "inform7/Chapter 15/Kind Checking.w"
kind *values_of_kind_variables[MAX_KIND_VARIABLES];
#line 94 "inform7/Chapter 15/Kind Checking.w"
int kind_checker_mode = MATCH_KIND_VARIABLES_AS_SYMBOLS;
#line 110 "inform7/Chapter 15/Kind Checking.w"
#line 112 "inform7/Chapter 15/Kind Constructors.w"
#line 125 "inform7/Chapter 15/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 80 "inform7/Chapter 15/Kind Interpreter.w"
#line 97 "inform7/Chapter 15/Kind Interpreter.w"
#line 108 "inform7/Chapter 15/Kind Interpreter.w"
#line 118 "inform7/Chapter 15/Kind Interpreter.w"
#line 122 "inform7/Chapter 15/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 181 "inform7/Chapter 15/Kind Interpreter.w"
#line 190 "inform7/Chapter 15/Kind Interpreter.w"
#line 197 "inform7/Chapter 15/Kind Interpreter.w"
#line 208 "inform7/Chapter 15/Kind Interpreter.w"
#line 24 "inform7/Chapter 15/Describing Kinds.w"
#line 31 "inform7/Chapter 15/Describing Kinds.w"
int kind_parsing_mode = NORMAL_KIND_PARSING;
#line 69 "inform7/Chapter 15/Dimensions.w"
#line 76 "inform7/Chapter 15/Dimensions.w"
#line 181 "inform7/Chapter 15/Dimensions.w"
#line 197 "inform7/Chapter 15/Dimensions.w"
#line 317 "inform7/Chapter 15/Dimensions.w"
#line 75 "inform7/Chapter 15/Scaled Arithmetic Values.w"
#line 125 "inform7/Chapter 16/Taxonomy of Specifications.w"
#line 171 "inform7/Chapter 16/Taxonomy of Specifications.w"
#line 53 "inform7/Chapter 16/Specifications.w"
int new_spec_count = 0, copied_spec_count = 0; /* for the debugging log */
#line 55 "inform7/Chapter 16/Compiling from Specifications.w"
int compilation_mode = DEREFERENCE_POINTERS_CMODE + IMPLY_NEWLINES_IN_SAY_CMODE; /* default */
#line 24 "inform7/Chapter 16/VALUE Specifications.w"
#line 26 "inform7/Chapter 16/CONDITION Specifications.w"
#line 36 "inform7/Chapter 16/CONDITION Specifications.w"
#line 75 "inform7/Chapter 16/Invocations.w"
#line 80 "inform7/Chapter 16/Invocations.w"
#line 101 "inform7/Chapter 16/Invocations.w"
#line 134 "inform7/Chapter 16/Invocations.w"
#line 153 "inform7/Chapter 16/Invocations.w"
#line 76 "inform7/Chapter 17/Properties.w"
#line 81 "inform7/Chapter 17/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 17/The Provision Relation.w"
binary_predicate *R_provision = NULL;
#line 78 "inform7/Chapter 17/Measurement Adjectives.w"
#line 91 "inform7/Chapter 17/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 28 "inform7/Chapter 17/Properties of Values.w"
property_of_value_storage *latest_povs = NULL; /* see below */
#line 63 "inform7/Chapter 18/Introduction to the Model World.w"
inference_subject *model_world = NULL;
inference_subject *nonlocal_variables = NULL;
inference_subject *global_constants = NULL;
inference_subject *relations = NULL;
#line 52 "inform7/Chapter 18/Inference Subjects.w"
#line 84 "inform7/Chapter 18/Property Permissions.w"
#line 63 "inform7/Chapter 18/Inferences.w"
int prevailing_mood = UNKNOWN_CE;
#line 88 "inform7/Chapter 18/Inferences.w"
#line 14 "inform7/Chapter 18/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;
property *P_list_together = NULL; /* I6 only: workspace for listing groups */
#line 30 "inform7/Chapter 18/The Naming Thicket.w"
STREAM SNAMES_struct;
STREAM *SNAMES = NULL;
int sn_r_counter = 0;
#line 24 "inform7/Chapter 18/Instance Counting.w"
#line 30 "inform7/Chapter 18/Instance Counting.w"
property *P_vector = NULL;
property *P_KD_Count = NULL; /* see below */
#line 52 "inform7/Chapter 19/Spatial Model.w"
#line 67 "inform7/Chapter 19/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 19/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 19/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 19/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 19/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 19/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 19/Regions.w"
binary_predicate *R_regional_containment = NULL;
#line 22 "inform7/Chapter 19/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 19/Regions.w"
#line 58 "inform7/Chapter 19/The Map.w"
#line 66 "inform7/Chapter 19/The Map.w"
kind *K_direction = NULL;
kind *K_door = NULL;
instance *I_up = NULL;
instance *I_down = NULL;
#line 78 "inform7/Chapter 19/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 19/Map Connection Relations.w"
binary_predicate *R_adjacency = NULL;
#line 25 "inform7/Chapter 19/Spatial Geometry.w"
#line 31 "inform7/Chapter 19/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 55 "inform7/Chapter 19/Spatial Geometry.w"
#line 83 "inform7/Chapter 19/Spatial Map.w"
#line 87 "inform7/Chapter 19/Spatial Map.w"
cuboid Universe;
#line 93 "inform7/Chapter 19/Spatial Map.w"
instance *benchmark_room = NULL;
#line 113 "inform7/Chapter 19/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 19/EPS Map.w"
int write_EPS_format_map = FALSE;
#line 47 "inform7/Chapter 19/EPS Map.w"
#line 59 "inform7/Chapter 19/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 19/EPS Map.w"
#line 135 "inform7/Chapter 19/EPS Map.w"
#line 140 "inform7/Chapter 19/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 19/EPS Map.w"
int index_map_with_pass = 0;
parse_node *index_map_with_p = NULL;
#line 36 "inform7/Chapter 19/Scenes.w"
#line 53 "inform7/Chapter 19/Scenes.w"
#line 57 "inform7/Chapter 19/Scenes.w"
property *P_recurring = NULL;
#line 62 "inform7/Chapter 19/Scenes.w"
scene *SC_entire_game = NULL;
#line 68 "inform7/Chapter 19/Scenes.w"
kind *K_scene = NULL;
#line 64 "inform7/Chapter 20/Text Literals.w"
#line 70 "inform7/Chapter 20/Text Literals.w"
literal_text *root_of_literal_text = NULL;
literal_text *z_node = NULL;
#line 83 "inform7/Chapter 20/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 37 "inform7/Chapter 20/Text Substitutions.w"
#line 41 "inform7/Chapter 20/Text Substitutions.w"
int no_further_text_subs = FALSE;
#line 47 "inform7/Chapter 20/Text Substitutions.w"
int compiling_text_routines_mode = FALSE; /* used for better problem messages */
#line 27 "inform7/Chapter 20/Responses.w"
#line 41 "inform7/Chapter 20/Nonlocal Variables.w"
#line 46 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable *i6_glob_VAR = NULL;
nonlocal_variable *i6_nothing_VAR = NULL; /* the I6 |nothing| constant */
#line 52 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable *latest_nonlocal_variable = NULL;
#line 24 "inform7/Chapter 20/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 20/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 20/Release Instructions.w"
#line 38 "inform7/Chapter 20/List Constants.w"
#line 47 "inform7/Chapter 20/List Constants.w"
#line 35 "inform7/Chapter 20/Table Columns.w"
#line 56 "inform7/Chapter 20/Table Columns.w"
#line 47 "inform7/Chapter 20/Tables.w"
#line 55 "inform7/Chapter 20/Tables.w"
#line 59 "inform7/Chapter 20/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 21/Equations.w"
#line 59 "inform7/Chapter 21/Equations.w"
#line 64 "inform7/Chapter 21/Equations.w"
equation_symbol *standard_equation_symbols = NULL;
#line 122 "inform7/Chapter 21/Equations.w"
#line 31 "inform7/Chapter 21/Inform 6 Inclusions.w"
#line 61 "inform7/Chapter 21/Inform 6 Inclusions.w"
#line 65 "inform7/Chapter 21/Inform 6 Inclusions.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 83 "inform7/Chapter 21/Inform 6 Inclusions.w"
#line 27 "inform7/Chapter 21/List Together.w"
#line 90 "inform7/Chapter 22/Phrases.w"
#line 94 "inform7/Chapter 22/Phrases.w"
struct phrase *first_in_logical_order = NULL;
#line 39 "inform7/Chapter 22/Phrase Usage.w"
#line 40 "inform7/Chapter 22/Phrase Runtime Context Data.w"
#line 64 "inform7/Chapter 22/Phrase Type Data.w"
#line 75 "inform7/Chapter 22/Phrase Type Data.w"
#line 110 "inform7/Chapter 22/Phrase Type Data.w"
#line 147 "inform7/Chapter 22/Phrase Type Data.w"
#line 33 "inform7/Chapter 22/Phrase Options.w"
#line 40 "inform7/Chapter 22/Phrase Options.w"
#line 43 "inform7/Chapter 22/Local Variables.w"
#line 69 "inform7/Chapter 22/Local Variables.w"
#line 35 "inform7/Chapter 22/Phrase Blocks.w"
#line 44 "inform7/Chapter 22/Phrase Blocks.w"
#line 34 "inform7/Chapter 22/Stack Frames.w"
#line 45 "inform7/Chapter 22/Stack Frames.w"
#line 60 "inform7/Chapter 22/Stack Frames.w"
#line 28 "inform7/Chapter 22/Compile Invocations.w"
#line 38 "inform7/Chapter 22/Compile Invocations.w"
#line 15 "inform7/Chapter 22/Compile Phrases.w"
phrase *phrase_being_compiled = NULL; /* phrase whose definition is being compiled */
#line 23 "inform7/Chapter 22/To Phrases.w"
#line 27 "inform7/Chapter 22/Phrases as Values.w"
#line 39 "inform7/Chapter 22/Adjectival Definitions.w"
#line 31 "inform7/Chapter 22/Timed Phrases.w"
#line 63 "inform7/Chapter 23/Rules.w"
#line 67 "inform7/Chapter 23/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 23/Rules.w"
#line 32 "inform7/Chapter 23/Rule Bookings.w"
#line 73 "inform7/Chapter 23/Rulebooks.w"
#line 87 "inform7/Chapter 23/Rulebooks.w"
#line 99 "inform7/Chapter 23/Rulebooks.w"
#line 107 "inform7/Chapter 23/Rulebooks.w"
rulebook *built_in_rulebooks[MAX_BUILT_IN_RULEBOOKS];
struct stacked_variable_owner_list *all_action_processing_vars = NULL;
#line 38 "inform7/Chapter 23/Focus and Outcome.w"
#line 68 "inform7/Chapter 23/Focus and Outcome.w"
#line 77 "inform7/Chapter 23/Focus and Outcome.w"
#line 84 "inform7/Chapter 23/Focus and Outcome.w"
#line 48 "inform7/Chapter 23/Stacked Variables.w"
int max_frame_size_needed = 0;
#line 43 "inform7/Chapter 24/Chronology.w"
#line 54 "inform7/Chapter 24/Chronology.w"
#line 60 "inform7/Chapter 24/Chronology.w"
#line 70 "inform7/Chapter 24/Actions.w"
stacked_variable_owner_list *all_nonempty_stacked_action_vars = NULL;
#line 76 "inform7/Chapter 24/Actions.w"
action_name *going_action = NULL;
#line 98 "inform7/Chapter 24/Actions.w"
kind *K_action_name = NULL;
kind *K_description_of_action = NULL;
kind *K_stored_action = NULL;
#line 68 "inform7/Chapter 24/Action Patterns.w"
#line 76 "inform7/Chapter 24/Action Patterns.w"
#line 91 "inform7/Chapter 24/Action Patterns.w"
int pap_failure_reason; /* one of the above */
int permit_trying_omission = FALSE; /* allow the keyword 'trying' to be omitted */
#line 31 "inform7/Chapter 24/Actions Index.w"
command_index_entry *sorted_command_index = NULL; /* in alphabetical order of |text| */
#line 23 "inform7/Chapter 25/Traverse for Grammar.w"
#line 32 "inform7/Chapter 25/Traverse for Grammar.w"
#line 43 "inform7/Chapter 25/Traverse for Grammar.w"
#line 17 "inform7/Chapter 25/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 38 "inform7/Chapter 25/Grammar Properties.w"
#line 48 "inform7/Chapter 25/Grammar Properties.w"
#line 72 "inform7/Chapter 25/Grammar Verbs.w"
int no_verb_verb_defined = FALSE;
#line 83 "inform7/Chapter 25/Grammar Verbs.w"
#line 64 "inform7/Chapter 25/Grammar Lines.w"
#line 74 "inform7/Chapter 25/Grammar Lines.w"
#line 38 "inform7/Chapter 25/Test Scripts.w"
#line 48 "inform7/Chapter 25/Test Scripts.w"
#line 26 "inform7/Chapter 26/Figures.w"
#line 30 "inform7/Chapter 26/Figures.w"
blorb_figure *F_cover_art = NULL;
#line 38 "inform7/Chapter 26/Figures.w"
kind *K_figure_name = NULL;
#line 27 "inform7/Chapter 26/Sound Effects.w"
#line 34 "inform7/Chapter 26/Sound Effects.w"
kind *K_sound_name = NULL;
#line 31 "inform7/Chapter 26/External Files.w"
#line 36 "inform7/Chapter 26/External Files.w"
kind *K_external_file = NULL;
#line 14 "inform7/Chapter 27/Main Routine.w"
struct tm *the_present = NULL;
#line 35 "inform7/Chapter 27/I6 Template Interpreter.w"
#line 39 "inform7/Chapter 27/I6 Template Interpreter.w"
int do_not_generate_index = FALSE;
#line 33 "inform7/Chapter 27/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;
#line 51 "inform7/Chapter 27/Plugins.w"
plugin_call *plugins_stack[MAX_PLUGS];
plugin *registered_plugins[MAX_PLUGINS];
#line 54 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef PLATFORM_MACOSX
#define FOLDER_SEPARATOR '/'
#define INFORM_FOLDER_RELATIVE_TO_HOME "Library/"
#define HOME_LIBRARY "/Library/Inform/Extensions"
#define HOME_LANGUAGES "/Library/Inform/Languages"
#define HOME_DOCS "/Library/Inform/Documentation"
#define HOME_TEMPLATES "/Library/Inform/Templates"
#define TELEMETRYFILE "/Library/Inform/Telemetry"
#define OPTIONSFILE "/Library/Inform/Options.txt"
#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 82 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef PLATFORM_WINDOWS
#define LOCALE_IS_ISO
#define FOLDER_SEPARATOR '\\'
#define INFORM_FOLDER_RELATIVE_TO_HOME ""
#define HOME_LIBRARY "\\Inform\\Extensions"
#define HOME_LANGUAGES "\\Inform\\Languages"
#define HOME_DOCS "\\Inform\\Documentation"
#define HOME_TEMPLATES "\\Inform\\Templates"
#define TELEMETRYFILE "\\Inform\\Telemetry"
#define OPTIONSFILE "\\Inform\\Options.txt"
#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 116 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef PLATFORM_WINDOWS
#define isdigit(x) Windows_specific_isdigit(x)
int Windows_specific_isdigit(int c) {
return ((c >= '0') && (c <= '9')) ? 1 : 0;
}
#endif
#line 129 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef PLATFORM_UNIX
#include <strings.h>
#line 132 "inform7/Chapter 1/Platform-Specific Definitions.w"
#define FOLDER_SEPARATOR '/'
#define INFORM_FOLDER_RELATIVE_TO_HOME ""
#define HOME_LIBRARY "/Inform/Extensions"
#define HOME_LANGUAGES "/Inform/Languages"
#define HOME_DOCS "/Inform/Documentation"
#define HOME_TEMPLATES "/Inform/Templates"
#define TELEMETRYFILE "/Inform/Telemetry"
#define OPTIONSFILE "/Inform/Options.txt"
#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 154 "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 169 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef POSIX_DIRECTORY_HANDLING
#include <sys/stat.h>
#include <sys/types.h>
#line 173 "inform7/Chapter 1/Platform-Specific Definitions.w"
#include <dirent.h>
int Platform__platform_specific_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;
STREAM_WRITE(STDERR, "Failed to create folder <%s>\n", transcoded_pathname);
return FALSE;
}
void *Platform__platform_specific_opendir(char *path_to_folder) {
DIR *dirp = opendir(path_to_folder);
return (void *) dirp;
}
int Platform__platform_specific_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) {
STREAM_WRITE(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__platform_specific_closedir(void *folder) {
DIR *dirp = (DIR *) folder;
closedir(dirp);
}
#endif
#line 222 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef WINDOWS_DIRECTORY_HANDLING
#include <sys/stat.h>
#include <direct.h>
#include <dirent.h>
#line 227 "inform7/Chapter 1/Platform-Specific Definitions.w"
#include <io.h>
int Platform__platform_specific_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;
STREAM_WRITE(STDERR, "Failed to create folder <%s>\n", transcoded_pathname);
return FALSE;
}
void *Platform__platform_specific_opendir(char *path_to_folder) {
DIR *dirp = opendir(path_to_folder);
return (void *) dirp;
}
int Platform__platform_specific_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) {
STREAM_WRITE(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__platform_specific_closedir(void *folder) {
DIR *dirp = (DIR *) folder;
closedir(dirp);
}
#endif
#line 280 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifndef LOCALE_IS_ISO
#ifndef LOCALE_IS_UTF8
#define LOCALE_IS_UTF8 1
#endif
#endif
#line 298 "inform7/Chapter 1/Platform-Specific Definitions.w"
FILE *Platform__iso_fopen(char *pathname, char *usage) {
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(char *pathname, char *usage) {
char transcoded_pathname[2*MAX_FILENAME_LENGTH];
Platform__transcode_ISO_string_to_locale(pathname, transcoded_pathname);
return Files__case_insensitive_fopen(transcoded_pathname, usage);
}
#line 313 "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 339 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef LOCALE_IS_ISO
int Platform__truncated_locale_fgets(FILE *F, char *buffer, int limit) {
return Files__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 = Text__Reader__utf8_fgetc(F, NULL, FALSE)) != EOF) {
if (len >= limit) break;
if ((c == '\x0a') || (c == '\x0d')) break;
if ((c >= 0x0300) && (c <= 0x036F) && (len > 0))
c = Formats__HTML__combining_accent(c, buffer[--len]);
buffer[len++] = (char) c;
}
buffer[len++] = 0;
return len;
}
#endif
#line 366 "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 = Text__Reader__utf8_fgetc(NULL, &arg, FALSE)) != 0) {
if (len >= limit) break;
if ((c == '\x0a') || (c == '\x0d')) break;
if ((c >= 0x0300) && (c <= 0x036F) && (len > 0))
c = Formats__HTML__combining_accent(c, buffer[--len]);
buffer[len++] = (char) c;
}
buffer[len++] = 0;
}
#endif
#line 390 "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 279 "inform7/Chapter 2/Memory.w"
#line 285 "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 348 "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 362 "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 372 "inform7/Chapter 2/Memory.w"
void allocate_another_block(void) {
unsigned char *cp;
memblock_header *mh;
{
#line 391 "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");
check_memory_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 376 "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 409 "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 382 "inform7/Chapter 2/Memory.w"
;
LOGIF(MEMORY_ALLOCATION, "AOB->the_memory: %08x\n", (pointer_sized_int) mh->the_memory);
}
#line 423 "inform7/Chapter 2/Memory.w"
void Memory__free_memory(void) {
I7_free_all_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 452 "inform7/Chapter 2/Memory.w"
#line 458 "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 469 "inform7/Chapter 2/Memory.w"
int calls_to_cmi = 0;
void check_memory_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");
debug_memory_frames(c-20, c-1);
internal_error("Memory manager failed integrity check");
}
LOGIF(MEMORY_ALLOCATION, "*** Succeeded ***\n");
}
void debug_memory_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 506 "inform7/Chapter 2/Memory.w"
void *allocate_mem(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 544 "inform7/Chapter 2/Memory.w"
if (current_memblock_header == NULL) allocate_another_block();
bytes_free_in_current_memblock = MEMORY_GRANULARITY - (used_in_current_memblock + extent);
if (bytes_free_in_current_memblock < BLANK_END_SIZE) {
allocate_another_block();
if (extent+BLANK_END_SIZE >= MEMORY_GRANULARITY)
Problems__Fatal__issue("Memory manager failed because granularity too low");
}
}
#line 514 "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 555 "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 526 "inform7/Chapter 2/Memory.w"
;
{
#line 563 "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 527 "inform7/Chapter 2/Memory.w"
;
no_frames_allocated++;
return (void *) cp;
}
#line 695 "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(combinator)
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(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(meaning_list)
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(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)
#line 813 "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_list_entry, 1000)
ALLOCATE_IN_ARRAYS(ap_optional_clause, 400)
ALLOCATE_IN_ARRAYS(application, 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(description_docket, 100)
ALLOCATE_IN_ARRAYS(dimensional_rule, 100)
ALLOCATE_IN_ARRAYS(extension_identifier_database_entry, 100)
ALLOCATE_IN_ARRAYS(i6_schema, 100)
ALLOCATE_IN_ARRAYS(inference, 100)
ALLOCATE_IN_ARRAYS(invocation_list_entry, 100)
ALLOCATE_IN_ARRAYS(invocation_list, 100)
ALLOCATE_IN_ARRAYS(invocation_options, 100)
ALLOCATE_IN_ARRAYS(invocation_token_list, 500)
ALLOCATE_IN_ARRAYS(invocation, 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(phrase_option, 100)
ALLOCATE_IN_ARRAYS(placement_affecting, 100)
ALLOCATE_IN_ARRAYS(plugin_call, 100)
ALLOCATE_IN_ARRAYS(scene_connector, 1000)
ALLOCATE_IN_ARRAYS(single_integer, 100)
ALLOCATE_IN_ARRAYS(specification, 100)
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(time_period, 100)
ALLOCATE_IN_ARRAYS(table_contribution, 100)
ALLOCATE_IN_ARRAYS(taxon, 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)
ALLOCATE_IN_ARRAYS(instance_usage, 200)
ALLOCATE_IN_ARRAYS(STREAM, 50)
#line 881 "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"
};
#line 905 "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 917 "inform7/Chapter 2/Memory.w"
void *Memory__I7_calloc(int how_many, int size_in_bytes, int reason) {
return I7_alloc(how_many, size_in_bytes, reason);
}
void *Memory__I7_malloc(int size_in_bytes, int reason) {
return I7_alloc(-1, size_in_bytes, reason);
}
#line 927 "inform7/Chapter 2/Memory.w"
void *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 961 "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 931 "inform7/Chapter 2/Memory.w"
;
{
#line 945 "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__memory_allocation_problem(_P_(BelievedImpossible), /* i.e., not reliably testable */
memory_needs[R]);
}
#line 932 "inform7/Chapter 2/Memory.w"
;
{
#line 971 "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 933 "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 984 "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 1006 "inform7/Chapter 2/Memory.w"
void I7_free_all_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 1020 "inform7/Chapter 2/Memory.w"
int log_I7_alloc_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 1039 "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 = log_I7_alloc_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 1074 "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), compare_usage_entries);
}
#line 1045 "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 1057 "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 1049 "inform7/Chapter 2/Memory.w"
;
int overhead_for_objects = total_for_objects - total_for_objects_used; /* bytes wasted */
{
#line 1081 "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);
}
}
log_I7_alloc_usage(total);
LOG("\nNOTES:\nSpecifications: %d created, %d copies made\n",
new_spec_count, copied_spec_count);
LOG("Permanent MLs: %d; Ephemeral MLs: %d; GAP movements: %d\n",
no_permanent_MLs, no_ephemeral_MLs, GAP_movements);
LOG("Created %d base kinds, %d intermediate kinds, %d constructed kinds\n",
no_base_kinds_created, no_intermediate_kinds_created, no_constructed_kinds_created);
}
#line 1051 "inform7/Chapter 2/Memory.w"
;
}
#line 1119 "inform7/Chapter 2/Memory.w"
int compare_usage_entries(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 1129 "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 1161 "inform7/Chapter 2/Memory.w"
general_pointer 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 test_gp_null(general_pointer gp) {
if (gp.run_time_type_code == -1) return TRUE;
return FALSE;
}
#line 1220 "inform7/Chapter 2/Memory.w"
MAKE_REFERENCE_ROUTINES(char, 1000)
#line 1293 "inform7/Chapter 2/Memory.w"
KCONVERSION_ROUTINES(action_name, action_name)
CONVERSION_ROUTINES(COMBINATION, CON_combination, combinator)
KCONVERSION_ROUTINES(equation, equation)
CONVERSION_ROUTINES(MAP, CON_phrase, constant_phrase)
OCONVERSION_ROUTINES(instance)
CONVERSION_ROUTINES(RELATION, CON_relation, binary_predicate)
KCONVERSION_ROUTINES(rulebook_outcome, named_rulebook_outcome)
KCONVERSION_ROUTINES(scene, scene)
KCONVERSION_ROUTINES(table, table)
KCONVERSION_ROUTINES(understanding, grammar_verb)
KCONVERSION_ROUTINES(use_option, use_option)
KCONVERSION_ROUTINES(verb, verb_conjugation)
#line 24 "inform7/Chapter 2/Single Integers.w"
int Memory__SingleIntegers__get(single_integer *sint) {
if (sint == NULL) return 0;
return sint->the_integer;
}
single_integer *Memory__SingleIntegers__new(int t) {
single_integer *sint = CREATE(single_integer);
sint->the_integer = t;
return sint;
}
#line 268 "inform7/Chapter 2/Streams.w"
void stream_initialise(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"
STREAM STDOUT_struct; int stdout_wrapper_initialised = FALSE;
STREAM *stream_get_stdout(void) {
if (stdout_wrapper_initialised == FALSE) {
stream_initialise(&STDOUT_struct); STDOUT_struct.write_to_file = stdout;
stdout_wrapper_initialised = TRUE;
}
return &STDOUT_struct;
}
#line 300 "inform7/Chapter 2/Streams.w"
STREAM STDERR_struct; int stderr_wrapper_initialised = FALSE;
STREAM *stream_get_stderr(void) {
if (stderr_wrapper_initialised == FALSE) {
stream_initialise(&STDERR_struct); STDERR_struct.write_to_file = stderr;
stderr_wrapper_initialised = TRUE;
}
return &STDERR_struct;
}
#line 314 "inform7/Chapter 2/Streams.w"
int stream_open_to_file(STREAM *stream, char *filename, int encoding) {
if (stream == NULL) internal_error("tried to open NULL stream");
if (filename == NULL) internal_error("stream_open_to_file on null filename");
stream_initialise(stream);
stream->write_to_file = Platform__iso_fopen(filename, "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 stream_open_to_file_append(STREAM *stream, char *filename, int encoding) {
if (stream == NULL) internal_error("tried to open NULL stream");
if (filename == NULL) internal_error("stream_open_to_file on null filename");
stream_initialise(stream);
stream->write_to_file = Platform__iso_fopen(filename, "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 stream_open_to_memory(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");
stream_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"
STREAM stream_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");
STREAM stream;
stream_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 stream_flush(STREAM *stream) {
if (stream == NULL) return;
if (stream->write_to_file) fflush(stream->write_to_file);
}
#line 388 "inform7/Chapter 2/Streams.w"
void stream_close(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) {
stream_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 stream_printf(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++) {
while (stream->stream_continues) stream = stream->stream_continues;
switch (*p) {
case '%':
{
#line 609 "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(STREAM)) + 32;
void *further_allocation = Memory__I7_malloc(needed, STREAM_MREASON);
if (further_allocation == NULL) Problems__Fatal__issue("Out of memory");
STREAM *continuation = (STREAM *) (further_allocation + offset);
stream_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 446 "inform7/Chapter 2/Streams.w"
;
{
#line 582 "inform7/Chapter 2/Streams.w"
if (stream->indentation_pending) {
stream->indentation_pending = FALSE;
int i;
for (i=0; i<stream->indentation_level; i++) {
stream_putc(' ', stream); stream_putc(' ', stream);
stream_putc(' ', stream); stream_putc(' ', stream);
}
}
}
#line 447 "inform7/Chapter 2/Streams.w"
;
{
#line 469 "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);
if (stream->write_to_file) fprintf(stream->write_to_file, format_string, ival);
if (stream->write_to_memory) {
sprintf(stream->write_to_memory + stream->chars_written, format_string, ival);
stream->chars_written += Platform__strlen(stream->write_to_memory + stream->chars_written);
}
break;
case 'g':
dval = va_arg(ap, double);
if (stream->write_to_file) fprintf(stream->write_to_file, format_string, dval);
if (stream->write_to_memory) {
sprintf(stream->write_to_memory + stream->chars_written, format_string, dval);
stream->chars_written += Platform__strlen(stream->write_to_memory + stream->chars_written);
}
break;
case 's':
for (sval = va_arg(ap, char *); *sval; sval++)
stream_putc(*sval, stream);
break;
case '%': stream_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 448 "inform7/Chapter 2/Streams.w"
; break;
default: stream_putc(*p, stream); break;
}
}
va_end(ap); /* macro to end variable argument processing */
}
#line 514 "inform7/Chapter 2/Streams.w"
void stream_putc(int c_int, 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;
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 582 "inform7/Chapter 2/Streams.w"
if (stream->indentation_pending) {
stream->indentation_pending = FALSE;
int i;
for (i=0; i<stream->indentation_level; i++) {
stream_putc(' ', stream); stream_putc(' ', stream);
stream_putc(' ', stream); stream_putc(' ', stream);
}
}
}
#line 533 "inform7/Chapter 2/Streams.w"
;
if (stream->use_xml_escapes) {
switch(c) {
case NEWLINE_IN_STRING: stream_literal(stream, "<br>"); return;
case '&': stream_literal(stream, "&amp;"); return;
case '<': stream_literal(stream, "&lt;"); return;
case '>': stream_literal(stream, "&gt;"); return;
}
}
while (stream->stream_continues) stream = stream->stream_continues;
{
#line 609 "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(STREAM)) + 32;
void *further_allocation = Memory__I7_malloc(needed, STREAM_MREASON);
if (further_allocation == NULL) Problems__Fatal__issue("Out of memory");
STREAM *continuation = (STREAM *) (further_allocation + offset);
stream_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 543 "inform7/Chapter 2/Streams.w"
;
if (stream->write_to_file) {
switch(stream->encoding_to_write_to_file) {
case UTF8_ENC:
{
#line 570 "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 546 "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') stream->indentation_pending = TRUE;
stream->chars_written++;
}
#line 629 "inform7/Chapter 2/Streams.w"
void stream_literal(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++) stream_putc((int) p[i], stream);
stream->use_xml_escapes = x;
}
#line 644 "inform7/Chapter 2/Streams.w"
void stream_indent(STREAM *stream) {
if (stream == NULL) return;
stream->indentation_level++;
}
void stream_outdent(STREAM *stream) {
if (stream == NULL) return;
stream->indentation_level--;
if ((stream->indentation_level < 0) && (problem_count == 0))
internal_error("stream indentation negative");
}
void set_stream_indentation(STREAM *stream, int N) {
if (stream == NULL) return;
stream->indentation_level = N;
}
#line 668 "inform7/Chapter 2/Streams.w"
int stream_get_position(STREAM *stream) {
int t = 0;
while (stream) {
t += stream->chars_written;
stream = stream->stream_continues;
}
return t;
}
#line 682 "inform7/Chapter 2/Streams.w"
int stream_latest(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 701 "inform7/Chapter 2/Streams.w"
void stream_set_position(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) {
stream_close(stream->stream_continues);
stream->stream_continues = NULL;
}
}
}
#line 728 "inform7/Chapter 2/Streams.w"
char *stream_get_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;
}
#line 738 "inform7/Chapter 2/Streams.w"
void stream_copy(STREAM *to, 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];
stream_putc(c, to);
}
if (from->stream_continues) stream_copy(to, from->stream_continues);
}
}
#line 51 "inform7/Chapter 2/Filenames.w"
char *bundle_name = NULL;
char *source_text_file = NULL;
#line 133 "inform7/Chapter 2/Filenames.w"
char filename_of_telemetry[MAX_FILENAME_LENGTH];
char filename_of_options[MAX_FILENAME_LENGTH];
char filename_of_epsfile[MAX_FILENAME_LENGTH];
char pathname_of_extensions[MAX_FILENAME_LENGTH];
char pathname_of_languages[MAX_FILENAME_LENGTH];
char pathname_of_templates[MAX_FILENAME_LENGTH];
char pathname_of_extension_docs[MAX_FILENAME_LENGTH];
char pathname_of_bundle[MAX_FILENAME_LENGTH];
char pathname_of_built_in_extensions[MAX_FILENAME_LENGTH];
char materials_folder[MAX_FILENAME_LENGTH];
char pathname_of_materials_extensions[MAX_FILENAME_LENGTH];
void Files__Filenames__make_pathname_of_extensions(void) {
char *home = (char *) (getenv("HOME"));
if (home == NULL) home = "";
strcpy(pathname_of_extensions, home); strcat(pathname_of_extensions, HOME_LIBRARY);
strcpy(pathname_of_languages, home); strcat(pathname_of_languages, HOME_LANGUAGES);
strcpy(pathname_of_extension_docs, home); strcat(pathname_of_extension_docs, HOME_DOCS);
strcpy(pathname_of_built_in_extensions, pathname_of_extensions);
strcpy(pathname_of_templates, home); strcat(pathname_of_templates, HOME_TEMPLATES);
strcpy(filename_of_options, home); strcat(filename_of_options, OPTIONSFILE);
strcpy(filename_of_telemetry, home); strcat(filename_of_telemetry, TELEMETRYFILE);
int this_month = the_present->tm_mon + 1;
int this_day = the_present->tm_mday;
int this_year = the_present->tm_year + 1900;
sprintf(filename_of_telemetry + Platform__strlen(filename_of_telemetry),
" %04d-%02d-%02d.txt", this_year, this_month, this_day);
}
#line 170 "inform7/Chapter 2/Filenames.w"
#line 174 "inform7/Chapter 2/Filenames.w"
void Files__Filenames__make_pathname_of_materials_folder(void) {
if (bundle_name) strcpy(materials_folder, bundle_name);
else materials_folder[0] = 0;
int i = Platform__strlen(materials_folder)-1;
while ((i>0) && (materials_folder[i] != '.')) i--;
if (i>0) strcpy(materials_folder+i, ".materials");
sprintf(pathname_of_materials_extensions, "%s%cExtensions",
materials_folder, FOLDER_SEPARATOR);
sprintf(filename_of_epsfile, "%s%cInform Map.eps",
materials_folder, FOLDER_SEPARATOR);
}
#line 194 "inform7/Chapter 2/Filenames.w"
char local_filename_buffer[MAX_FILENAME_LENGTH];
char *Files__Filenames__top_level(char *leafname) {
if (bundle_name == NULL) return leafname; /* outside bundle mode, use current directory */
sprintf(local_filename_buffer, "%s%c%s",
bundle_name, FOLDER_SEPARATOR, leafname);
return local_filename_buffer;
}
#line 211 "inform7/Chapter 2/Filenames.w"
char *Files__Filenames__build(char *leafname) {
if (census_mode) {
if (Files__Folders__verify_installed_extensions_tree() == FALSE) return leafname;
sprintf(local_filename_buffer, "%s%c%s",
pathname_of_extension_docs, FOLDER_SEPARATOR, leafname);
return local_filename_buffer;
}
if (bundle_name == NULL) return leafname;
sprintf(local_filename_buffer, "%s%cBuild%c%s",
bundle_name, FOLDER_SEPARATOR, FOLDER_SEPARATOR, leafname);
return local_filename_buffer;
}
#line 229 "inform7/Chapter 2/Filenames.w"
char *source_filename(char *leafname) {
if (bundle_name == NULL) return leafname;
sprintf(local_filename_buffer, "%s%cSource%c%s",
bundle_name, FOLDER_SEPARATOR, FOLDER_SEPARATOR, leafname);
return local_filename_buffer;
}
char *Files__Filenames__source_filename_relative_to_bundle(char *leafname) {
if (bundle_name == NULL) return leafname;
sprintf(local_filename_buffer, "Source%c%s",
FOLDER_SEPARATOR, leafname);
return local_filename_buffer;
}
#line 250 "inform7/Chapter 2/Filenames.w"
int index_subfolder_made = FALSE;
int details_subfolder_made = FALSE;
char *Files__Filenames__index(char *leafname, int sub) {
if (bundle_name == NULL) return leafname;
if (index_subfolder_made == FALSE) {
sprintf(local_filename_buffer, "%s%cIndex",
bundle_name, FOLDER_SEPARATOR);
Platform__platform_specific_mkdir(local_filename_buffer);
index_subfolder_made = TRUE;
}
sprintf(local_filename_buffer, "%s%cIndex%c",
bundle_name, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
if (sub >= 0) {
strcat(local_filename_buffer, "Details");
if (details_subfolder_made == FALSE) {
Platform__platform_specific_mkdir(local_filename_buffer);
details_subfolder_made = TRUE;
}
sprintf(local_filename_buffer + Platform__strlen(local_filename_buffer),
"%c%d_", FOLDER_SEPARATOR, sub);
}
sprintf(local_filename_buffer + Platform__strlen(local_filename_buffer), "%s", leafname);
return local_filename_buffer;
}
#line 292 "inform7/Chapter 2/Filenames.w"
int Files__Folders__verify_library_folder(char *p1, char *p2, char *p3, char *new) {
char path[MAX_FILENAME_LENGTH];
char *home = (char *) (getenv("HOME"));
int rv;
path[0] = 0;
if (home) sprintf(path, "%s%c", home, FOLDER_SEPARATOR);
sprintf(path + Platform__strlen(path), "%s", INFORM_FOLDER_RELATIVE_TO_HOME);
if (p1) sprintf(path + Platform__strlen(path), "%s%c", p1, FOLDER_SEPARATOR);
if (p2) sprintf(path + Platform__strlen(path), "%s%c", p2, FOLDER_SEPARATOR);
if (p3) sprintf(path + Platform__strlen(path), "%s%c", p3, FOLDER_SEPARATOR);
if (new) sprintf(path + Platform__strlen(path), "%s", new);
rv = Platform__platform_specific_mkdir(path);
if (rv == FALSE) LOG("Files__Folders__verify_library_folder failed on path %s\n", path);
return rv;
}
#line 319 "inform7/Chapter 2/Filenames.w"
int Files__Folders__verify_installed_extensions_tree(void) {
if (Files__Folders__verify_library_folder(NULL, NULL, NULL, "Inform") == 0) return FALSE;
if (Files__Folders__verify_library_folder("Inform", NULL, NULL, "Documentation") == 0) return FALSE;
if (Files__Folders__verify_library_folder("Inform", "Documentation", NULL, "Extensions") == 0) return FALSE;
if (Files__Folders__verify_library_folder("Inform", NULL, NULL, "Extensions") == 0) return FALSE;
if (Files__Folders__verify_library_folder("Inform", "Extensions", NULL, "Reserved") == 0) return FALSE;
return TRUE;
}
#line 342 "inform7/Chapter 2/Filenames.w"
int Files__Folders__write_contents_to_file(char *pathname, char *writeto) {
STREAM CONTS_struct; STREAM *CONTS = &CONTS_struct;
void *FOLDER = Platform__platform_specific_opendir(pathname);
char leafname[MAX_FILENAME_LENGTH+1];
if (FOLDER == NULL) return FALSE;
if (STREAM_OPEN_TO_FILE(CONTS, writeto, ISO_ENC) == FALSE) return FALSE;
while (Platform__platform_specific_readdir(FOLDER, pathname, leafname)) {
if (leafname[0] == '.') continue;
STREAM_WRITE(CONTS, "%s\n", leafname);
}
STREAM_CLOSE(CONTS);
Platform__platform_specific_closedir(FOLDER);
return TRUE;
}
#line 360 "inform7/Chapter 2/Filenames.w"
int Files__Folders__write_contents_to_stream(OUTPUT_STREAM, char *pathname) {
void *FOLDER = Platform__platform_specific_opendir(pathname);
if (FOLDER == NULL) return FALSE;
char leafname[MAX_FILENAME_LENGTH+1];
while (Platform__platform_specific_readdir(FOLDER, pathname, leafname)) {
if (leafname[0] == '.') continue;
WRITE("%s\n", leafname);
}
Platform__platform_specific_closedir(FOLDER);
return TRUE;
}
#line 380 "inform7/Chapter 2/Filenames.w"
int Files__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 49 "inform7/Chapter 2/Case-Insensitive Filenames.w"
#ifdef POSIX_DIRECTORY_HANDLING
#line 58 "inform7/Chapter 2/Case-Insensitive Filenames.w"
FILE *Files__case_insensitive_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, "Files__case_insensitive_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 153 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: succeeded\n");
{
#line 167 "inform7/Chapter 2/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 154 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return handle;
}
#line 67 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
{
#line 179 "inform7/Chapter 2/Case-Insensitive Filenames.w"
length = 0;
if (path) length = (size_t) Platform__strlen(path);
if (length < 1) { errno = ENOENT; return NULL; }
}
#line 69 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
{
#line 137 "inform7/Chapter 2/Case-Insensitive Filenames.w"
workstring = calloc(length+1, sizeof(char));
if (workstring == NULL) { errno = ENOMEM;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 138 "inform7/Chapter 2/Case-Insensitive Filenames.w"
; }
workstring2 = calloc(length+1, sizeof(char));
if (workstring2 == NULL) { errno = ENOMEM;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 140 "inform7/Chapter 2/Case-Insensitive Filenames.w"
; }
topdirpath = calloc(length+1, sizeof(char));
if (topdirpath == NULL) { errno = ENOMEM;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 142 "inform7/Chapter 2/Case-Insensitive Filenames.w"
; }
ciextdirpath = calloc(length+1, sizeof(char));
if (ciextdirpath == NULL) { errno = ENOMEM;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 144 "inform7/Chapter 2/Case-Insensitive Filenames.w"
; }
cistring = calloc(length+1, sizeof(char));
if (cistring == NULL) { errno = ENOMEM;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 146 "inform7/Chapter 2/Case-Insensitive Filenames.w"
; }
ciextname = calloc(length+1, sizeof(char));
if (ciextname == NULL) { errno = ENOMEM;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 148 "inform7/Chapter 2/Case-Insensitive Filenames.w"
; }
}
#line 70 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
{
#line 196 "inform7/Chapter 2/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 71 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
topdir = opendir(topdirpath); /* whose pathname is assumed case-correct... */
if (topdir == NULL)
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 74 "inform7/Chapter 2/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 95 "inform7/Chapter 2/Case-Insensitive Filenames.w"
int rc = count_matches_within_directory(topdir, ciextdirpath, workstring);
switch (rc) {
case 0:
errno = ENOENT;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 98 "inform7/Chapter 2/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 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 105 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
}
break;
default:
errno = EBADF;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 109 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
}
}
#line 79 "inform7/Chapter 2/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 153 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: succeeded\n");
{
#line 167 "inform7/Chapter 2/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 154 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return handle;
}
#line 85 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
{
#line 116 "inform7/Chapter 2/Case-Insensitive Filenames.w"
int rc = count_matches_within_directory(extdir, ciextname, workstring);
switch (rc) {
case 0:
errno = ENOENT;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 120 "inform7/Chapter 2/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 153 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: succeeded\n");
{
#line 167 "inform7/Chapter 2/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 154 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return handle;
}
#line 126 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "Couldn't open %s\n", workstring2);
errno = ENOENT;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 128 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
default:
errno = EBADF;
{
#line 160 "inform7/Chapter 2/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 167 "inform7/Chapter 2/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 161 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 130 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
}
}
#line 87 "inform7/Chapter 2/Case-Insensitive Filenames.w"
;
}
#line 231 "inform7/Chapter 2/Case-Insensitive Filenames.w"
int count_matches_within_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, "count_matches_within_directory rc = %d\n", rc);
return rc;
}
#line 253 "inform7/Chapter 2/Case-Insensitive Filenames.w"
#else
FILE *Files__case_insensitive_fopen(const char *path, const char *mode) {
return fopen(path, mode);
}
#endif
#line 29 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compose_identifier(char *ledger,
char nature_character, int id_number, int w1, int w2) {
int j;
char identifier[64];
sprintf(identifier, "%c%d", nature_character, id_number);
if ((w1>=0) && (w2>=w1)) {
for (j=w1; j<=w2; j++) {
/* identifier is at this point 32 chars or fewer in length: add at most 30 more */
if (Platform__strlen(Text__word_text(j)) > 30) sprintf(identifier + Platform__strlen(identifier), " etc");
else sprintf(identifier + Platform__strlen(identifier), " %s", Text__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 */
Formats__Inform6__purify_identifier(identifier);
strcpy(ledger, identifier);
}
#line 50 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__purify_identifier(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 76 "inform7/Chapter 2/Make Inform 6 Names.w"
sentence_handler TRANSLATES_SH_handler =
{ SENTENCE_NT, TRANSLATES_VB, 0, translates_into_I6_as };
#line 85 "inform7/Chapter 2/Make Inform 6 Names.w"
int translates_into_i6_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 97 "inform7/Chapter 2/Make Inform 6 Names.w"
*X = INVALID_I6TR;
Problems__sentence_problem(_P_(C2TranslatedUnknownCategory),
"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 92 "inform7/Chapter 2/Make Inform 6 Names.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 93 "inform7/Chapter 2/Make Inform 6 Names.w"
#line 110 "inform7/Chapter 2/Make Inform 6 Names.w"
int translates_into_i6_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 113 "inform7/Chapter 2/Make Inform 6 Names.w"
#line 117 "inform7/Chapter 2/Make Inform 6 Names.w"
void translates_into_I6_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;
int w1 = -1, w2 = -1;
parse_nt_against_word_range(translates_into_i6_sentence_subject_NTM, p1->word_ref1, p1->word_ref2, NULL, NULL);
category = most_recent_result;
if (category == INVALID_I6TR) return;
GET_RW(translates_into_i6_sentence_subject_NTM, 1, w1, w2);
if (traverse == 1) {
Parser__Nodes__annotate_int(pn, category_of_I6_translation_ANNOT, INVALID_I6TR);
{
#line 162 "inform7/Chapter 2/Make Inform 6 Names.w"
int valid = TRUE, x1, x2;
x1 = p2->word_ref1; x2 = p2->word_ref2;
if (parse_nt_against_word_range(translates_into_i6_sentence_object_NTM, x1, x2, NULL, NULL) == FALSE) valid = FALSE;
else responses_list = most_recent_result_p;
if (valid)
{
#line 179 "inform7/Chapter 2/Make Inform 6 Names.w"
int i;
char *p;
p2->word_ref1 = x1;
Text__dequote_word(x1);
p = Text__word_text(x1);
if ((Platform__strlen(p) == 0) || (Platform__strlen(p) > 31)) valid = FALSE;
for (i=0; p[i]; i++)
if ((isdigit(p[i]) == 0) && (isalpha(p[i]) == 0) && (p[i] != '_'))
valid = FALSE;
if (isdigit(p[0])) valid = FALSE;
}
#line 166 "inform7/Chapter 2/Make Inform 6 Names.w"
;
if (valid == FALSE) {
Problems__sentence_problem(_P_(C2TranslatedToNonIdentifier),
"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 130 "inform7/Chapter 2/Make Inform 6 Names.w"
;
Parser__Nodes__annotate_int(pn, category_of_I6_translation_ANNOT, category);
if (responses_list) Parser__Nodes__graft(responses_list, p2);
} else category = Parser__Nodes__int_annotation(pn, category_of_I6_translation_ANNOT);
{
#line 142 "inform7/Chapter 2/Make Inform 6 Names.w"
switch(category) {
case PROPERTY_I6TR:
Properties__translates(w1, w2, p2);
Parser__Nodes__annotate_int(pn, category_of_I6_translation_ANNOT, INVALID_I6TR); break;
case NAMETAG_I6TR: break;
case RULE_I6TR:
if (traverse == 1) Code__Rules__declare_I6_written_rule(w1, w2, p2);
if ((traverse == 2) && (p2->down) && (parse_nt_against_word_range(rule_name_NTM, w1, w2, NULL, NULL)))
add_extra_responses_to_rule(p2->down, most_recent_result_p);
break;
case VARIABLE_I6TR: if (traverse == 2) Data__NonlocalVariables__translates(w1, w2, p2); break;
case ACTION_I6TR: if (traverse == 2) Plugins__Actions__translates(w1, w2, p2); break;
case GRAMMAR_TOKEN_I6TR: if (traverse == 2) Plugins__Parsing__Verbs__translates(w1, w2, p2); break;
}
}
#line 135 "inform7/Chapter 2/Make Inform 6 Names.w"
;
}
#line 193 "inform7/Chapter 2/Make Inform 6 Names.w"
int extra_response_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 195 "inform7/Chapter 2/Make Inform 6 Names.w"
#line 199 "inform7/Chapter 2/Make Inform 6 Names.w"
void add_extra_responses_to_rule(parse_node *p, rule *R) {
if (Parser__Nodes__type(p) == AND_NT) {
add_extra_responses_to_rule(p->down, R);
add_extra_responses_to_rule(p->down->next, R);
} else {
if (parse_nt_against_word_range(extra_response_NTM, p->word_ref1, p->word_ref2, NULL, NULL)) {
int code = most_recent_result;
response_message *resp = Data__Strings__response_cue(NULL, R,
code, p->word_ref1, NULL, TRUE);
Code__Rules__now_rule_defines_response(R, code, resp);
} else {
Problems__sentence_problem(_P_(C2I6ResponsesAwry),
"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 250 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_dictionary_word(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 298 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_string(OUTPUT_STREAM, char *p, int options) {
int i, from = 0, to = Platform__strlen(p), esc_digit = FALSE;
if ((options & ISN_DEQUOTE) && (p[0] == '"') && (p[to-1] == '"')) {
from++; to--;
}
if (options & ISN_RAW) {
for (i=from; i<to; i++) {
if ((i == from) && (options & ISN_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 & ISN_BOX_QUOTATION) WRITE("\"\n\"");
else WRITE(" ");
break;
case '\t':
if (options & ISN_BOX_QUOTATION) WRITE("\"\n\"");
else WRITE(" ");
break;
case NEWLINE_IN_STRING:
if (options & ISN_BOX_QUOTATION) WRITE("\"\n\"");
else WRITE("^"); break;
case '"': WRITE("~"); break;
case '@':
if (options & ISN_FOR_ARRAY) WRITE("@{40}");
else { WRITE("@@64"); esc_digit = TRUE; continue; }
break;
case '^':
if (options & ISN_BOX_QUOTATION) WRITE("\"\n\"");
else if (options & ISN_FOR_ARRAY) WRITE("@{5E}");
else { WRITE("@@94"); esc_digit = TRUE; continue; }
break;
case '~':
if (options & ISN_FOR_ARRAY) WRITE("@{7E}");
else { WRITE("@@126"); esc_digit = TRUE; continue; }
break;
case '\\': WRITE("@{5C}"); break;
case '\'':
if (options & ISN_EXPAND_APOSTROPHES)
{
#line 372 "inform7/Chapter 2/Make Inform 6 Names.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]) && (isalpha_accented(up[i-1])) && (isalpha_accented(up[i+1])))
WRITE("'"); /* allow apostrophe sandwiched between two letters */
else WRITE("~"); /* and otherwise convert to double-quote */
}
#line 341 "inform7/Chapter 2/Make Inform 6 Names.w"
else WRITE("'");
break;
case '[':
if ((options & ISN_RECOGNISE_APOSTROPHE_SUBSTITUTION) &&
(p[i+1] == '\'') && (p[i+2] == ']')) { i += 2; WRITE("'"); }
else if (options & ISN_RECOGNISE_UNICODE_SUBSTITUTION) {
int n = Formats__Inform6__expand_unisub(OUT, p, i);
if (n == -1) WRITE("["); else i = n;
} else WRITE("[");
break;
default:
if ((i==from) && (options & ISN_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 382 "inform7/Chapter 2/Make Inform 6 Names.w"
int isalpha_accented(int letter) {
return isalpha(Formats__HTML__without_accent(letter));
}
#line 391 "inform7/Chapter 2/Make Inform 6 Names.w"
int Formats__Inform6__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;
int x1 = lexer_wordcount;
Text__feed_into_lexer(substitution_buffer, FALSE, NULL);
int x2 = lexer_wordcount-1;
if (parse_nt_against_word_range(unicode_character_NTM, x1, x2, NULL, NULL) == FALSE) return -1;
PUT(most_recent_result);
return j;
} else return -1;
} else return -1;
}
#line 414 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_text(OUTPUT_STREAM, int w1, int w2, int opts, int raw) {
int j;
for (j=w1; j<=w2; j++) {
char *p;
if (raw) p = Text__word_raw_text(j); else p = Text__word_text(j);
Formats__Inform6__compile_string(OUT, p, opts);
if (j<w2) WRITE(" ");
}
}
#line 427 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_as_comment(OUTPUT_STREAM, int w1, int w2) {
Formats__Inform6__compile_text(OUT, w1, w2, 0, FALSE);
}
void Formats__Inform6__compile_text_simply(OUTPUT_STREAM, int w1, int w2) {
Formats__Inform6__compile_text(OUT, w1, w2, 0, TRUE);
}
#line 438 "inform7/Chapter 2/Make Inform 6 Names.w"
void Formats__Inform6__compile_divider_comment(OUTPUT_STREAM) {
WRITE("! -------------------------------------------------"
"---------------------------------------------------\n");
}
#line 42 "inform7/Chapter 2/Inform 6 Labels.w"
label_namespace *lns_new(char *name) {
label_namespace *lns;
int i;
if (Platform__strlen(name) > MAX_NAMESPACE_PREFIX_LENGTH)
Problems__sentence_problem(_P_(C2LabelNamespaceTooLong),
"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 2/Inform 6 Labels.w"
label_namespace *lns_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 *lns_read_or_create(char *name) {
label_namespace *lns = lns_by_prefix(name);
if (lns == NULL) lns = lns_new(name);
return lns;
}
#line 83 "inform7/Chapter 2/Inform 6 Labels.w"
int Formats__Inform6__Labels__Counters__read(char *namespace, int advance_flag) {
label_namespace *lns = lns_read_or_create(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 Formats__Inform6__Labels__write(OUTPUT_STREAM, char *namespace) {
label_namespace *lns = lns_read_or_create(namespace);
WRITE("L_%s%d", lns->label_prefix, lns->label_counter);
}
#line 108 "inform7/Chapter 2/Inform 6 Labels.w"
void Formats__Inform6__Labels__Counters__allocate(char *namespace, int multiplier) {
label_namespace *lns = lns_read_or_create(namespace);
if (multiplier > lns->allocate_storage) lns->allocate_storage = multiplier;
}
void Formats__Inform6__Labels__Counters__compile_allocated_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 15 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__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 Files__Formats__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 Files__Formats__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 Files__Formats__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 78 "inform7/Chapter 2/Image Dimensions.w"
void Files__Formats__swap_bytes32(unsigned int *value) {
unsigned int result = (((*value & 0xff) << 24) +
((*value & 0xff00) << 8) +
((*value & 0xff0000) >> 8) +
((*value & 0xff000000) >> 24 ) );
*value = result;
}
void Files__Formats__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 104 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__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 121 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__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 (!Files__Formats__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 146 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__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 173 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__JPEG__get_dimensions(FILE *JPEG_file, unsigned int *width, unsigned int *height) {
unsigned int sig, length;
int marker;
if (!Files__Formats__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 (!Files__Formats__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 (!Files__Formats__read_int16(JPEG_file, height)) return FALSE;
if (!Files__Formats__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 226 "inform7/Chapter 2/Image Dimensions.w"
int Files__Formats__PNG__get_dimensions(FILE *PNG_file, unsigned int *width, unsigned int *height) {
unsigned int sig1, sig2, length, type;
/* Check PNG signature */
if (!Files__Formats__read_int32(PNG_file, &sig1)) return FALSE;
if (!Files__Formats__read_int32(PNG_file, &sig2)) return FALSE;
if ((sig1 != 0x89504e47) || (sig2 != 0x0d0a1a0a)) return FALSE;
/* Read first chunk */
if (!Files__Formats__read_int32(PNG_file, &length)) return FALSE;
if (!Files__Formats__read_int32(PNG_file, &type)) return FALSE;
/* First chunk must be IHDR */
if (type != 0x49484452) return FALSE;
/* Width and height follow */
if (!Files__Formats__read_int32(PNG_file, width)) return FALSE;
if (!Files__Formats__read_int32(PNG_file, height)) return FALSE;
return TRUE;
}
#line 15 "inform7/Chapter 2/Sound Durations.w"
int Files__Formats__AIFF__get_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 (!Files__Formats__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x464F524D) return FALSE; /* |"FORM"| indicating an IFF file */
if (!Files__Formats__read_int32(pFile, &sig)) return FALSE;
if (!Files__Formats__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 (!Files__Formats__read_int32(pFile, &chunkID)) return FALSE;
if (!Files__Formats__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 (!Files__Formats__read_int16(pFile, pChannels)) return FALSE;
if (!Files__Formats__read_int32(pFile, &numSampleFrames)) return FALSE;
if (!Files__Formats__read_int16(pFile, &sampleSize)) return FALSE;
if (!Files__Formats__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 2/Sound Durations.w"
int Files__Formats__OggVorbis__get_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 (!Files__Formats__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x4F676753) return FALSE; /* |"OggS"| indicating an OGG file */
/* Check OGG version is zero */
if (!Files__Formats__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 (!Files__Formats__read_int8(pFile, &numSegments)) return FALSE;
/* Skip segment table */
if (fseek(pFile, (long) numSegments, SEEK_CUR) != 0) return FALSE;
/* Vorbis Identification header */
if (!Files__Formats__read_int8(pFile, &packetType)) return FALSE;
if (packetType != 1) return FALSE;
if (!Files__Formats__read_int32(pFile, &vorbisSig1)) return FALSE;
if (vorbisSig1 != 0x766F7262) return FALSE; /* |"VORB"| */
if (!Files__Formats__read_int16(pFile, &vorbisSig2)) return FALSE;
if (vorbisSig2 != 0x6973) return FALSE; /* |"IS"| */
/* Check Vorbis version is zero */
if (!Files__Formats__read_int32(pFile, &version)) return FALSE;
if (version != 0) return FALSE;
/* Read number of channels */
if (!Files__Formats__read_int8(pFile, pChannels)) return FALSE;
/* Read sample rate */
if (!Files__Formats__read_int32(pFile, pSampleRate)) return FALSE;
Files__Formats__swap_bytes32(pSampleRate); /* Ogg Vorbis uses LSB first */
/* Skip bitrate maximum */
if (fseek(pFile, 4, SEEK_CUR) != 0) return FALSE;
/* Read Nominal Bitrate */
if (!Files__Formats__read_int32(pFile, pBitsPerSecond)) return FALSE;
Files__Formats__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 (!Files__Formats__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x4F676753) return FALSE; /* |"OggS"| indicating an OGG file */
/* Check OGG version is zero */
if (!Files__Formats__read_int8(pFile, &version)) return FALSE;
if (version != 0) return FALSE;
/* Skip header Type */
if (fseek(pFile, 1, SEEK_CUR) != 0) return FALSE;
if (!Files__Formats__read_int64(pFile, &granulePosition)) return FALSE;
Files__Formats__swap_bytes64(&granulePosition);
*pDuration = (unsigned int) ((granulePosition * 100) /
(unsigned long long) *pSampleRate);
return TRUE;
}
#line 184 "inform7/Chapter 2/Sound Durations.w"
int Files__Formats__Midi__get_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 (!Files__Formats__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 (!Files__Formats__read_int32(pFile, &sig)) return FALSE;
}
/* |"MThd"| indicating a MIDI file */
if (sig != 0x4D546864) return FALSE;
/* Read length of chunk */
if (!Files__Formats__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 (!Files__Formats__read_int16(pFile, pType)) return FALSE;
/* Read the number of tracks */
if (!Files__Formats__read_int16(pFile, pNumTracks)) return FALSE;
/* Read "Pulses Per Quarter Note" (PPQN) */
if (!Files__Formats__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 (!Files__Formats__read_int32(pFile, &sig)) {
if (feof(pFile)) return TRUE;
return FALSE;
}
if (!Files__Formats__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 (!Files__Formats__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 (!Files__Formats__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 (!Files__Formats__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 (!Files__Formats__read_int8(pFile, &non_midi_event)) return FALSE;
if (!Files__Formats__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 (!Files__Formats__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 3/HTML Files.w"
void Formats__HTML__html_source_link(OUTPUT_STREAM, source_location sl, int nonbreaking_space) {
if (sl.file_of_origin) {
char *filename = Text__Reader__sf_get_filename(sl.file_of_origin);
if (bundle_name && (strncmp(filename, bundle_name, (size_t) Platform__strlen(bundle_name)) == 0))
filename += Platform__strlen(bundle_name) + 1;
if ((strncmp(filename, "Source", 6)==0) && (filename[6]==FOLDER_SEPARATOR))
filename += 7;
if (nonbreaking_space) WRITE("&nbsp;"); else WRITE(" ");
WRITE("<a href=\"source:%s#line%d\"><img border=0 src=inform:/doc_images/Reveal.%s></a>",
filename, sl.line_number, ICON_EXT);
}
}
#line 118 "inform7/Chapter 3/HTML Files.w"
#line 125 "inform7/Chapter 3/HTML Files.w"
void Formats__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 180 "inform7/Chapter 3/HTML Files.w"
int outcome_image_style = SIDE_OUTCOME_IMAGE_STYLE;
void Formats__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_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:
Formats__HTML__begin_html_table(OUT, NULL, TRUE, 0, 4, 0, 0, 0);
Formats__HTML__first_html_column(OUT, 110);
WRITE("<img src=inform:/outcome_images/%s%s@2x.png "
"border=1 width=100 height=100>", image, vn);
Formats__HTML__next_html_column(OUT, 0);
break;
}
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>");
}
void Formats__HTML__outcome_image_tail(OUTPUT_STREAM) {
if (outcome_image_style == SIDE_OUTCOME_IMAGE_STYLE) {
Formats__HTML__end_html_row(OUT);
Formats__HTML__end_html_table(OUT);
}
}
#line 250 "inform7/Chapter 3/HTML Files.w"
void Formats__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><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 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();
WRITE("</head>\n");
WRITE("<body>");
if (JAVASCRIPT_MODEL == 1) {
WRITE("<script language=\"JavaScript\">");
WRITE("function pasteCode(code) { ");
WRITE("var myProject = window.Project; ");
WRITE("myProject.selectView('source'); ");
WRITE("myProject.pasteCode(code); ");
WRITE("}");
WRITE("</script>\n");
}
WRITE("<font %s>\n", DEFAULT_HTML_FONT);
WRITE("<!--CONTENT BEGINS-->\n");
if (thumbnail) {
WRITE("<!--NAVIGATION BEGINS-->\n");
Formats__HTML__open_coloured_box(OUT, "e0e0e0", ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
Formats__HTML__begin_html_table(OUT, NULL, TRUE, 0, 0, 0, 0, 0);
Formats__HTML__first_html_column(OUT, 72);
WRITE("<img border=1 src=inform:/doc_images/%s title=\"%s\"> ", thumbnail, caption);
Formats__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 Formats__HTML__html_header_complete(OUTPUT_STREAM, char *title, char *thumbnail) {
if (thumbnail) {
Formats__HTML__end_html_row(OUT); Formats__HTML__end_html_table(OUT);
Formats__HTML__close_coloured_box(OUT, "e0e0e0", ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
WRITE("</p><p>");
WRITE("\n<!--NAVIGATION ENDS-->\n");
}
}
void Formats__HTML__html_footer(OUTPUT_STREAM) {
WRITE("\n<!--CONTENT ENDS-->\n");
WRITE("</font></body></html>");
}
#line 437 "inform7/Chapter 3/HTML Files.w"
void Formats__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 448 "inform7/Chapter 3/HTML Files.w"
void 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++) {
Formats__HTML__open_para(ifl, k, ""); INDEX(text); INDEX("</p>");
}
for (k=1; k<4; k++) {
Formats__HTML__open_para(ifl, k, "tight"); INDEX(text); INDEX("</p>");
}
for (k=1; k<4; k++) {
Formats__HTML__open_para(ifl, k, "hanging"); INDEX(text); INDEX("</p>");
}
}
#line 492 "inform7/Chapter 3/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 Formats__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\">");
Formats__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 = Text__Reader__filename_to_source_file(source_ref_filename);
sl.line_number = atoi(source_ref_line);
Formats__HTML__html_source_link(OUT, sl, TRUE);
}
return;
default:
PUT(charcode);
return;
}
}
#line 546 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__begin_plain_html_table(OUTPUT_STREAM) {
Formats__HTML__begin_html_table(OUT, NULL, FALSE, 0, 0, 0, 0, 0);
}
void Formats__HTML__begin_wide_html_table(OUTPUT_STREAM) {
Formats__HTML__begin_html_table(OUT, NULL, TRUE, 0, 0, 0, 0, 0);
}
#line 559 "inform7/Chapter 3/HTML Files.w"
void Formats__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 Formats__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 Formats__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 Formats__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 Formats__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 Formats__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 Formats__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 Formats__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 Formats__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 Formats__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 Formats__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 Formats__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 Formats__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 Formats__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 Formats__HTML__end_html_row(OUTPUT_STREAM) {
WRITE("</font></td></tr>");
}
void Formats__HTML__end_html_table(OUTPUT_STREAM) {
WRITE("</table>");
}
#line 667 "inform7/Chapter 3/HTML Files.w"
void Formats__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) box_corner(OUT, html_colour, "tl");
WRITE("</td><td></td>");
WRITE("<td width=\"%d\">", CORNER_SIZE);
if (rounding & ROUND_BOX_TOP) 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 Formats__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) box_corner(OUT, html_colour, "bl");
WRITE("</td><td></td>");
WRITE("<td width=\"%d\">", CORNER_SIZE);
if (rounding & ROUND_BOX_BOTTOM) box_corner(OUT, html_colour, "br");
WRITE("</td></tr>", html_colour);
WRITE("</table>");
}
void 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 702 "inform7/Chapter 3/HTML Files.w"
void Formats__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 726 "inform7/Chapter 3/HTML Files.w"
void Formats__HTML__compile_bibliographic_text(OUTPUT_STREAM, char *p) {
if (p == NULL) return;
if (TEST_COMPILATION_MODE(COMPILE_TEXT_TO_XML_CMODE))
{
#line 743 "inform7/Chapter 3/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 (is_babel_whitespace(p[i])) i++; /* omit leading whitespace */
while ((i2>=0) && (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 = Formats__Inform6__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 729 "inform7/Chapter 3/HTML Files.w"
;
if (TEST_COMPILATION_MODE(TRUNCATE_TEXT_CMODE))
{
#line 871 "inform7/Chapter 3/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 904 "inform7/Chapter 3/HTML Files.w"
charcode = Formats__HTML__iso_remove_accents(charcode);
}
#line 886 "inform7/Chapter 3/HTML Files.w"
;
whitespace_count = 0;
if (charcode < 128) {
PUT(charcode); black_chars_written++;
}
break;
}
}
if (black_chars_written == 0) WRITE("story");
return;
}
#line 731 "inform7/Chapter 3/HTML Files.w"
;
if (TEST_COMPILATION_MODE(COMPILE_TEXT_TO_I6_CMODE))
{
#line 826 "inform7/Chapter 3/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 733 "inform7/Chapter 3/HTML Files.w"
{
#line 789 "inform7/Chapter 3/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 = Formats__Inform6__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 734 "inform7/Chapter 3/HTML Files.w"
;
}
#line 910 "inform7/Chapter 3/HTML Files.w"
int Formats__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 945 "inform7/Chapter 3/HTML Files.w"
int Formats__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 998 "inform7/Chapter 3/HTML Files.w"
int Formats__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 1026 "inform7/Chapter 3/HTML Files.w"
int is_babel_whitespace(char c) {
if ((c == ' ') || (c == '\t') || (c == '\x0a')
|| (c == '\x0d') || (c == NEWLINE_IN_STRING)) return TRUE;
return FALSE;
}
#line 1040 "inform7/Chapter 3/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", "C71585" },
{ "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", "C0C0C0" },
{ "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 1192 "inform7/Chapter 3/HTML Files.w"
char *Formats__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 96 "inform7/Chapter 3/Javascript Pastes.w"
int javascript_fn_counter = 1000;
void Formats__HTML__Javascript__paste(OUTPUT_STREAM, int from, int to, char *alt_text) {
switch(JAVASCRIPT_MODEL) {
case 1: /* OS X style, with long function arguments allowed in links */
WRITE("<a href=\"javascript:pasteCode(");
javascript_string_out(OUT, from, to, alt_text);
WRITE(")\"><img border=0 src=inform:/doc_images/paste.png></a>");
break;
case 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 = external.Project;\n\n");
WRITE("myProject.selectView('source');\n");
WRITE("myProject.pasteCode(");
OUTDENT; 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++);
break;
}
}
#line 124 "inform7/Chapter 3/Javascript Pastes.w"
void Formats__HTML__Javascript__open_file(OUTPUT_STREAM,
char *path1, char *path2, char *contents) {
int i;
switch(JAVASCRIPT_MODEL) {
case 1:
if (path2)
WRITE("<a href='javascript:window.Project.openFile(\"%s%c%s\")'>"
"%s</a>", path1, FOLDER_SEPARATOR, path2, contents);
else
WRITE("<a href='javascript:window.Project.openFile(\"%s\")'>"
"%s</a>", path1, contents);
break;
case 2:
WRITE("<a href='javascript:external.Project.openFile(\"");
for (i=0; path1[i]; i++)
if (path1[i] == '\\') PUT('/'); else PUT(path1[i]);
if (path2) {
PUT('/');
for (i=0; path2[i]; i++)
if (path2[i] == '\\') PUT('/'); else PUT(path2[i]);
}
WRITE("\")'>%s</a>", contents);
break;
}
}
#line 157 "inform7/Chapter 3/Javascript Pastes.w"
void javascript_string_out(OUTPUT_STREAM, int from, int to, char *C_string) {
WRITE("'");
if (C_string)
{
#line 167 "inform7/Chapter 3/Javascript Pastes.w"
int i;
for (i=0; C_string[i]; i++)
javascript_char_out(OUT, C_string[i]);
}
#line 159 "inform7/Chapter 3/Javascript Pastes.w"
;
if (from >= 0)
{
#line 194 "inform7/Chapter 3/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 = Text__word_raw_text(i);
if (Text__word(i) == PARBREAK_V) { /* marker for a paragraph break */
javascript_char_out(OUT, '\n');
javascript_char_out(OUT, '\n');
suppress_space = TRUE;
follows_paragraph_break = TRUE;
while (Text__word(i) == PARBREAK_V) i++; i--; /* elide multiple breaks */
continue;
}
int indentation = Text__indentation_level(i);
if (indentation > 0) { /* number of tab stops of indentation on this para */
javascript_char_out(OUT, '\n');
for (j=0; j<indentation-1; j++) javascript_char_out(OUT, '\t');
suppress_space = TRUE;
}
if ((Text__break_before(i) == '\t') && (follows_paragraph_break == FALSE)) {
javascript_char_out(OUT, '\t');
suppress_space = TRUE;
}
follows_paragraph_break = FALSE;
if (suppress_space==FALSE)
{
#line 232 "inform7/Chapter 3/Javascript Pastes.w"
if ((i>from)
&& ((p[1] != 0) || (Text__is_punctuation(p[0]) == FALSE) ||
(p[0] == '(') || (p[0] == '{') || (p[0] == '}'))
&& (compare_word(i-1, OPENBRACKET_V)==FALSE))
javascript_char_out(OUT, ' ');
}
#line 219 "inform7/Chapter 3/Javascript Pastes.w"
;
suppress_space = FALSE;
for (j=0; p[j]; j++) javascript_char_out(OUT, p[j]);
{
#line 247 "inform7/Chapter 3/Javascript Pastes.w"
if (Text__word(i) == OPENI6_V) close_I6_position = i+1;
if (close_I6_position == i) {
javascript_char_out(OUT, '-');
javascript_char_out(OUT, ')');
javascript_char_out(OUT, ' ');
}
}
#line 222 "inform7/Chapter 3/Javascript Pastes.w"
;
}
javascript_char_out(OUT, '\n');
javascript_char_out(OUT, '\n');
}
#line 160 "inform7/Chapter 3/Javascript Pastes.w"
;
WRITE("'");
}
#line 262 "inform7/Chapter 3/Javascript Pastes.w"
void 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 3/HTML Documentation.w"
void 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 3/HTML Documentation.w"
int extension_documentation_heading_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 3/HTML Documentation.w"
#line 76 "inform7/Chapter 3/HTML Documentation.w"
int extension_documentation_heading(int w1, int w2, int *level, int *hn1, int *hn2) {
if (parse_nt_against_word_range(extension_documentation_heading_NTM, w1, w2, NULL, NULL)) {
if (w1+10 >= w2) return FALSE; /* not enough space: this runs into the end-of-file padding */
*level = most_recent_result;
w1 += 2;
int end = w1; while ((end<=w2) && (Text__word(end) != PARBREAK_V)) end++; end--;
*hn1 = w1; *hn2 = end;
return TRUE;
}
return FALSE;
}
#line 97 "inform7/Chapter 3/HTML Documentation.w"
int extension_example_header_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 100 "inform7/Chapter 3/HTML Documentation.w"
int row_of_asterisks_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 106 "inform7/Chapter 3/HTML Documentation.w"
#line 110 "inform7/Chapter 3/HTML Documentation.w"
int extension_documentation_example(int w1, int w2,
int *asterisks, int *egn1, int *egn2, int *egr1, int *egr2) {
if (w1+10 >= w2) return FALSE; /* not enough space: this runs into the end-of-file padding */
if (parse_nt_against_word_range(extension_example_header_NTM, w1, w2, NULL, NULL)) {
int n1, n2, r1, r2;
GET_RW(extension_example_header_NTM, 1, n1, n2);
GET_RW(extension_example_header_NTM, 2, r1, r2);
r2 = r1;
while ((r2 <= w2) && ((Text__word(r2) == PARBREAK_V) == FALSE)) r2++;
if (r2 >= w2) return FALSE; r2--;
/* a successful match has now been made */
*asterisks = most_recent_result; *egn1 = n1; *egn2 = n2; *egr1 = r1; *egr2 = r2;
return TRUE;
}
return FALSE;
}
#line 146 "inform7/Chapter 3/HTML Documentation.w"
void Extensions__Documentation__HTML__set_table_of_contents(int w1, int w2, OUTPUT_STREAM, char *base_leafname) {
int i;
int heading_count = 0, chapter_count = 0, section_count = 0, example_count = 0;
for (i=w1; i<=w2; i++) {
int edhl, name_w1, name_w2, eg_rubric_w1, eg_rubric_w2, asterisks;
if (Text__word(i) == PARBREAK_V) { /* the lexer records this to mean a paragraph break */
while (Text__word(i) == PARBREAK_V) i++; if (i>w2) break;
if (extension_documentation_heading(i, w2, &edhl, &name_w1, &name_w2)) {
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 186 "inform7/Chapter 3/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");
}
Extensions__Documentation__HTML__set_body_text(name_w1, name_w2, OUT, EDOC_FRAGMENT_ONLY, NULL);
WRITE("%s<br>\n", html_to_close);
}
#line 161 "inform7/Chapter 3/HTML Documentation.w"
;
i = name_w2; continue;
}
if ((heading_count > 0) && (example_count < 26) &&
(extension_documentation_example(i, w2,
&asterisks, &name_w1, &name_w2, &eg_rubric_w1, &eg_rubric_w2))) {
if (++example_count == 1) WRITE("<br><b>Examples</b><br>");
{
#line 215 "inform7/Chapter 3/HTML Documentation.w"
WRITE("&nbsp;&nbsp;&nbsp;"); /* always indent TOC entries for examples */
WRITE("<a %s href=\"", EDOC_TOC_LINK_STYLE);
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 */
Extensions__Documentation__HTML__set_body_text(name_w1, name_w2, OUT, EDOC_FRAGMENT_ONLY, NULL);
WRITE("</font></a><br>");
}
#line 168 "inform7/Chapter 3/HTML Documentation.w"
;
i = eg_rubric_w2; continue;
}
}
}
if (heading_count > 0)
WRITE("<p><hr><p>"); /* ruled line at foot of TOC, if there is one */
}
#line 228 "inform7/Chapter 3/HTML Documentation.w"
int Extensions__Documentation__HTML__set_body_text(int w1, int w2, 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;
int i;
for (i=w1; i<=w2; i++) {
int edhl, name_w1, name_w2, eg_rubric_w1, eg_rubric_w2, asterisks;
if (Text__word(i) == PARBREAK_V) { /* the lexer records this to mean a paragraph break */
{
#line 282 "inform7/Chapter 3/HTML Documentation.w"
if (mid_displayed_source_text) {
WRITE("</font>");
if (mid_I7_table)
{
#line 509 "inform7/Chapter 3/HTML Documentation.w"
Formats__HTML__end_html_row(OUT);
Formats__HTML__end_html_table(OUT);
}
#line 284 "inform7/Chapter 3/HTML Documentation.w"
;
WRITE("</blockquote>");
}
WRITE("\n<p>\n");
mid_displayed_source_text = FALSE; mid_I7_table = FALSE;
}
#line 238 "inform7/Chapter 3/HTML Documentation.w"
;
while (Text__word(i) == PARBREAK_V) i++; if (i>w2) break; /* treat multiple paragraph breaks as one */
{
#line 298 "inform7/Chapter 3/HTML Documentation.w"
indentation = 0; if (Text__break_before(i) == '\t') indentation = 1;
}
#line 240 "inform7/Chapter 3/HTML Documentation.w"
;
if (extension_documentation_heading(i, w2, &edhl, &name_w1, &name_w2)) {
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 401 "inform7/Chapter 3/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;
}
Extensions__Documentation__HTML__set_body_text(name_w1, name_w2, OUT, EDOC_FRAGMENT_ONLY, NULL);
WRITE("</b></font>");
}
#line 248 "inform7/Chapter 3/HTML Documentation.w"
;
i = name_w2; continue;
}
if ((example_count < 26) && (extension_documentation_example(i, w2,
&asterisks, &name_w1, &name_w2, &eg_rubric_w1, &eg_rubric_w2))) {
skipping_text_of_an_example = FALSE;
if (mid_example)
{
#line 526 "inform7/Chapter 3/HTML Documentation.w"
Formats__HTML__end_html_row(OUT);
Formats__HTML__end_html_table(OUT);
WRITE("<p>");
}
#line 254 "inform7/Chapter 3/HTML Documentation.w"
;
mid_example = FALSE;
example_count++;
{
#line 423 "inform7/Chapter 3/HTML Documentation.w"
WRITE("<hr><p>"); /* rule a line before the example heading */
WRITE("<a name=eg%d>", example_count); /* provide the anchor point */
Formats__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 459 "inform7/Chapter 3/HTML Documentation.w"
Formats__HTML__begin_plain_html_table(OUT);
WRITE("<tr class=\"oval\"><td width=38px height=30px align=\"left\" valign=\"center\">");
{
#line 473 "inform7/Chapter 3/HTML Documentation.w"
WRITE("<a href=\"");
if (example_count == example_which_is_open) /* this example currently open */
href_of_example(OUT, base_leafname, EDOC_ALL_EXAMPLES_CLOSED, example_count);
else /* this example not yet open */
href_of_example(OUT, base_leafname, example_count, example_count);
WRITE("\" STYLE=\"text-decoration: none\">");
}
#line 461 "inform7/Chapter 3/HTML Documentation.w"
;
WRITE("<div class=\"paragraph Body\" style=\"line-height: 1px; margin-bottom: 0px; "
"margin-top: 4px; padding-bottom: 0pt; padding-top: 4px; text-align: center; "
"color: #202020; font-size: 14px; line-height: 1px;\"><b>%c</b></div>",
'A' + example_count - 1);
WRITE("</a></td></tr>");
Formats__HTML__end_html_table(OUT);
}
#line 430 "inform7/Chapter 3/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 473 "inform7/Chapter 3/HTML Documentation.w"
WRITE("<a href=\"");
if (example_count == example_which_is_open) /* this example currently open */
href_of_example(OUT, base_leafname, EDOC_ALL_EXAMPLES_CLOSED, example_count);
else /* this example not yet open */
href_of_example(OUT, base_leafname, example_count, example_count);
WRITE("\" STYLE=\"text-decoration: none\">");
}
#line 436 "inform7/Chapter 3/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\">");
Extensions__Documentation__HTML__set_body_text(name_w1, name_w2, OUT, EDOC_FRAGMENT_ONLY, base_leafname);
WRITE("</font></b></a>"); /* end the textual link */
WRITE("<br>");
Extensions__Documentation__HTML__set_body_text(eg_rubric_w1, eg_rubric_w2, OUT, EDOC_FRAGMENT_ONLY, base_leafname);
WRITE("<p>");
WRITE("</td></tr>");
Formats__HTML__end_html_table(OUT);
WRITE("<p>");
}
#line 257 "inform7/Chapter 3/HTML Documentation.w"
;
if (example_count == example_which_is_open) {
{
#line 519 "inform7/Chapter 3/HTML Documentation.w"
Formats__HTML__begin_html_table(OUT, "#f0f0f0", TRUE, 0, 0, 0, 0, 0);
Formats__HTML__first_html_column(OUT, 0);
WRITE("<p>");
}
#line 259 "inform7/Chapter 3/HTML Documentation.w"
;
mid_example = TRUE;
} else skipping_text_of_an_example = TRUE;
i = eg_rubric_w2; continue;
}
}
if (skipping_text_of_an_example) continue;
{
#line 313 "inform7/Chapter 3/HTML Documentation.w"
if (Text__indentation_level(i) > 0) indentation = Text__indentation_level(i);
if (indentation > 0)
{
#line 370 "inform7/Chapter 3/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 485 "inform7/Chapter 3/HTML Documentation.w"
WRITE("</font><br>");
Formats__HTML__begin_plain_html_table(OUT);
Formats__HTML__first_html_column(OUT, 0);
}
#line 375 "inform7/Chapter 3/HTML Documentation.w"
;
} else {
if (mid_I7_table)
{
#line 503 "inform7/Chapter 3/HTML Documentation.w"
Formats__HTML__end_html_row(OUT);
Formats__HTML__first_html_column(OUT, 0);
}
#line 377 "inform7/Chapter 3/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 ((parse_nt_against_word_range(structural_sentence_NTM, i, w2, NULL, NULL)) && (most_recent_result == TABLE_NT))
start_table_next_line = TRUE;
}
indentation--;
for (j=0; j<indentation; j++) WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
}
#line 315 "inform7/Chapter 3/HTML Documentation.w"
;
if (parse_nt_against_word_range(extension_documentation_paste_marker_NTM, i, w2, NULL, NULL)) {
int from, to;
GET_RW(extension_documentation_paste_marker_NTM, 1, from, to);
{
#line 351 "inform7/Chapter 3/HTML Documentation.w"
int x = i+2, y = w2, j;
for (j=x; j<=y; j++) /* first find the end of the quoted passage */
if (Text__word(j) == PARBREAK_V) {
int possible_end = j-1;
while (Text__word(j) == PARBREAK_V) j++;
if ((j<y) && ((Text__break_before(j) == '\t') || (Text__indentation_level(j) > 0))) continue;
y = possible_end; break;
}
Formats__HTML__Javascript__paste(OUT, x, y, NULL);
}
#line 319 "inform7/Chapter 3/HTML Documentation.w"
;
i++; continue;
}
indentation = 0;
if ((mid_I7_table) && ((Text__break_before(i) == '\t') || (Text__indentation_level(i) == 1))) {
if (row_of_table_is_empty == FALSE)
{
#line 492 "inform7/Chapter 3/HTML Documentation.w"
WRITE("</font>");
Formats__HTML__next_html_column(OUT, 0);
}
#line 325 "inform7/Chapter 3/HTML Documentation.w"
;
{
#line 498 "inform7/Chapter 3/HTML Documentation.w"
WRITE("<font color=\"#000080\">");
}
#line 326 "inform7/Chapter 3/HTML Documentation.w"
;
row_of_table_is_empty = FALSE;
}
}
#line 267 "inform7/Chapter 3/HTML Documentation.w"
;
{
#line 333 "inform7/Chapter 3/HTML Documentation.w"
char *p = Text__word_raw_text(i); int j;
if ((i>w1)
&& ((p[1] != 0) || (Text__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++) Formats__HTML__html_char_out(OUT, p[j]); /* set the actual word */
if (Text__word(i) == OPENI6_V) close_I6_position = i+1; /* ensure I6 literals are closed */
}
#line 268 "inform7/Chapter 3/HTML Documentation.w"
;
if (close_I6_position == i) WRITE(" -)");
}
if (mid_example)
{
#line 526 "inform7/Chapter 3/HTML Documentation.w"
Formats__HTML__end_html_row(OUT);
Formats__HTML__end_html_table(OUT);
WRITE("<p>");
}
#line 271 "inform7/Chapter 3/HTML Documentation.w"
;
if (example_which_is_open != EDOC_FRAGMENT_ONLY)
{
#line 282 "inform7/Chapter 3/HTML Documentation.w"
if (mid_displayed_source_text) {
WRITE("</font>");
if (mid_I7_table)
{
#line 509 "inform7/Chapter 3/HTML Documentation.w"
Formats__HTML__end_html_row(OUT);
Formats__HTML__end_html_table(OUT);
}
#line 284 "inform7/Chapter 3/HTML Documentation.w"
;
WRITE("</blockquote>");
}
WRITE("\n<p>\n");
mid_displayed_source_text = FALSE; mid_I7_table = FALSE;
}
#line 272 "inform7/Chapter 3/HTML Documentation.w"
;
return example_count;
}
#line 304 "inform7/Chapter 3/HTML Documentation.w"
int extension_documentation_paste_marker_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 306 "inform7/Chapter 3/HTML Documentation.w"
#line 89 "inform7/Chapter 3/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) {
char *fn = Files__Filenames__index(index_leaf, sub);
if (ifl) close_index_file();
if (STREAM_OPEN_TO_FILE(&index_file_struct, fn, UTF8_ENC) == FALSE)
Problems__Fatal__issue2("Can't open index file", fn);
ifl = &index_file_struct;
{
#line 175 "inform7/Chapter 3/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 154 "inform7/Chapter 3/Index File Services.w"
;
cti_set = FALSE;
Formats__HTML__html_header(ifl, title,
(cti_set)?current_thumbnail_image:NULL,
(cti_set)?current_thumbnail_caption:NULL);
index_file_counter++;
if (title[0] == '<') {
index_banner_line(1, "^", "Details",
"A single action in detail.|About the action rulebooks<ARSUMMARY>", "../Actions.html");
INDEX("<hr>");
}
{
#line 218 "inform7/Chapter 3/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 243 "inform7/Chapter 3/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 227 "inform7/Chapter 3/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 256 "inform7/Chapter 3/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 231 "inform7/Chapter 3/Index File Services.w"
;
index_element *ie;
LOOP_OVER(ie, index_element)
if (ie->owning_page == ip)
{
#line 270 "inform7/Chapter 3/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 235 "inform7/Chapter 3/Index File Services.w"
;
{
#line 288 "inform7/Chapter 3/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 236 "inform7/Chapter 3/Index File Services.w"
;
}
INDEX("</table></div>");
}
#line 166 "inform7/Chapter 3/Index File Services.w"
;
indexing_stage = TRUE;
if ((title[0] != '<') && (strcmp(index_leaf, "Welcome.html") != 0))
{
#line 309 "inform7/Chapter 3/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_banner_line(ie->atomic_number, ie->chemical_symbol,
ie->element_name, ie->explanatory_note, NULL);
index_page *save_ip = current_index_page;
index_actual_element(ie->chemical_symbol);
current_index_page = save_ip;
INDEX("</div>\n");
}
INDEX("<hr>\n");
}
#line 169 "inform7/Chapter 3/Index File Services.w"
;
}
#line 327 "inform7/Chapter 3/Index File Services.w"
void 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 337 "inform7/Chapter 3/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 329 "inform7/Chapter 3/Index File Services.w"
;
{
#line 351 "inform7/Chapter 3/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 330 "inform7/Chapter 3/Index File Services.w"
;
INDEX("</tr></table>\n");
}
#line 361 "inform7/Chapter 3/Index File Services.w"
void Index__scripting(void) {
if (current_index_page == NULL) return;
INDEX("<style type=\"text/css\" media=\"screen, print\">\n");
{
#line 390 "inform7/Chapter 3/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 365 "inform7/Chapter 3/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 536 "inform7/Chapter 3/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 375 "inform7/Chapter 3/Index File Services.w"
;
{
#line 553 "inform7/Chapter 3/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 376 "inform7/Chapter 3/Index File Services.w"
;
{
#line 565 "inform7/Chapter 3/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 378 "inform7/Chapter 3/Index File Services.w"
;
{
#line 577 "inform7/Chapter 3/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 379 "inform7/Chapter 3/Index File Services.w"
;
{
#line 590 "inform7/Chapter 3/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 380 "inform7/Chapter 3/Index File Services.w"
;
{
#line 602 "inform7/Chapter 3/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 382 "inform7/Chapter 3/Index File Services.w"
;
{
#line 612 "inform7/Chapter 3/Index File Services.w"
INDEX("function light_up(id) {\n");
{
#line 625 "inform7/Chapter 3/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 613 "inform7/Chapter 3/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 625 "inform7/Chapter 3/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 618 "inform7/Chapter 3/Index File Services.w"
;
INDEX(" document.getElementById(ic).style.background = '#cccccc';\n");
INDEX("}\n");
}
#line 383 "inform7/Chapter 3/Index File Services.w"
;
INDEX("</script>\n");
}
#line 634 "inform7/Chapter 3/Index File Services.w"
void index_actual_element(char *elt) {
if (strcmp(elt, "C") == 0) {
Parser__Sentences__Headings__index();
Extensions__Files__index();
Extensions__Files__update_census();
return;
}
if (strcmp(elt, "Vl") == 0) {
Data__NonlocalVariables__index_all();
Data__Equations__index();
return;
}
if (strcmp(elt, "Fi") == 0) {
Plugins__Figures__index_all();
Plugins__Sounds__index_all();
Plugins__Files__index_all();
return;
}
if (strcmp(elt, "Tb") == 0) {
Data__Tables__index();
return;
}
if (strcmp(elt, "Cd") == 0) {
Plugins__Bibliographic__index_library_card();
return;
}
if (strcmp(elt, "In") == 0) {
Code__VirtualMachines__index_innards();
return;
}
if (strcmp(elt, "Ph") == 0) {
Code__Phrases__index_page_Phrasebook();
return;
}
if (strcmp(elt, "Lx") == 0) {
Index__Lexicon__index();
return;
}
if (strcmp(elt, "Rl") == 0) {
Semantics__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) {
Plugins__Scenes__index();
return;
}
if (strcmp(elt, "Ev") == 0) {
Code__Phrases__Timed__index(); /* rules which happen at set times of day */
return;
}
if (strcmp(elt, "RS") == 0) {
Plugins__Scenes__index_rules();
return;
}
if (strcmp(elt, "St") == 0) {
Code__Rulebooks__index_page(1);
return;
}
if (strcmp(elt, "Xt") == 0) {
Code__Rulebooks__index_page(2);
return;
}
if (strcmp(elt, "A1") == 0) {
Plugins__Actions__Index__page();
return;
}
if (strcmp(elt, "Bh") == 0) {
Plugins__Actions__Patterns__Named__index();
return;
}
if (strcmp(elt, "Cm") == 0) {
Plugins__Actions__Index__commands();
return;
}
if (strcmp(elt, "To") == 0) {
Plugins__Actions__Index__tokens();
return;
}
if (strcmp(elt, "A2") == 0) {
Plugins__Actions__Index__alphabetical();
return;
}
INDEX("<p>NO CONTENT</p>");
}
#line 750 "inform7/Chapter 3/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__doc_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 786 "inform7/Chapter 3/Index File Services.w"
void Index__complete(void) {
if (ifl) close_index_file();
Plugins__Actions__Index__detail_pages();
}
void close_index_file(void) {
if (ifl == NULL) return;
Formats__HTML__html_footer(ifl);
STREAM_CLOSE(ifl); ifl = NULL;
}
#line 812 "inform7/Chapter 3/Index File Services.w"
void Index__link(int wn) {
link_to_location(ifl, Text__word_location(wn), TRUE);
}
void Index__link_location(source_location sl) {
link_to_location(ifl, sl, TRUE);
}
void Index__link_to(OUTPUT_STREAM, int wn, int nonbreaking_space) {
link_to_location(OUT, Text__word_location(wn), nonbreaking_space);
}
void link_to_location(OUTPUT_STREAM, source_location sl, int nonbreaking_space) {
extension_file *ef = Text__Reader__sf_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;
}
Formats__HTML__html_source_link(OUT, sl, nonbreaking_space);
}
#line 844 "inform7/Chapter 3/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 857 "inform7/Chapter 3/Index File Services.w"
sentence_handler DOC_SH_handler =
{ SENTENCE_NT, DOC_VB, 1, dref_new };
void dref_new(parse_node *p) {
int sym1, sym2, ref1, ref2;
sym1 = p->down->next->word_ref1; sym2 = p->down->next->word_ref2;
ref1 = p->down->next->next->word_ref1; ref2 = p->down->next->next->word_ref2;
char *chap = NULL, *sect = NULL;
if ((ref2 >= ref1+1) && (Text__Vocabulary__test_flags(ref1+1, TEXT_MC))) {
Text__dequote_word(ref1+1);
chap = Text__word_text(ref1+1);
}
if ((ref2 >= ref1+2) && (Text__Vocabulary__test_flags(ref1+2, TEXT_MC))) {
Text__dequote_word(ref1+2);
sect = Text__word_text(ref1+2);
}
int i;
for (i=sym1; i<=sym2; i++) {
documentation_ref *dr = CREATE(documentation_ref);
dr->symbol = i;
dr->section = ref1;
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 897 "inform7/Chapter 3/Index File Services.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 Text__word_text(dr->symbol);
return NULL;
}
#line 909 "inform7/Chapter 3/Index File Services.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 = Text__word_text(dr->section);
*chap = dr->chapter_reference;
*sec = dr->section_reference;
LOOP_OVER(dr, documentation_ref)
if (strcmp(leaf, Text__word_text(dr->section)) == 0)
dr->used_already = TRUE;
return leaf;
}
}
return NULL;
}
#line 934 "inform7/Chapter 3/Index File Services.w"
int documentation_symbol_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 937 "inform7/Chapter 3/Index File Services.w"
int documentation_symbol_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = documentation_symbol_NTM->range_result_w1[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 940 "inform7/Chapter 3/Index File Services.w"
#line 944 "inform7/Chapter 3/Index File Services.w"
int Index__DocReferences__position_of_symbol(int *w1, int *w2) {
if (parse_nt_against_word_range(documentation_symbol_tail_NTM, *w1, *w2, NULL, NULL)) {
GET_RW(documentation_symbol_tail_NTM, 1, *w1, *w2);
return most_recent_result;
}
return -1;
}
#line 957 "inform7/Chapter 3/Index File Services.w"
void Index__doc_mark_used(char *symb, int at_word) {
if (Log__Aspects__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 = Text__file_of_origin(at_word);
loc = Text__Reader__sf_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 983 "inform7/Chapter 3/Index File Services.w"
void Index__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 = Text__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 1001 "inform7/Chapter 3/Index File Services.w"
void Index__doc_link(char *fn) {
Index__doc_link_to(ifl, fn, FALSE);
}
void Index__doc_fully_link(char *fn) {
Index__doc_link_to(ifl, fn, TRUE);
}
void Index__doc_link_to(OUTPUT_STREAM, char *fn, int full) {
documentation_ref *dr = 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>",
Text__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 1028 "inform7/Chapter 3/Index File Services.w"
void Index__doc_fragment(char *fn) {
doc_fragment_to(ifl, fn);
}
int fragments_loaded = FALSE;
void doc_fragment_to(OUTPUT_STREAM, char *fn) {
if (fragments_loaded == FALSE) {
{
#line 1051 "inform7/Chapter 3/Index File Services.w"
char path_to_fragments[MAX_FILENAME_LENGTH];
sprintf(path_to_fragments, "%s%cReserved%cdefinitions.html",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
if (Files__Folders__verify_library_folder("Inform", "Extensions", NULL, "Reserved")) {
FILE *FRAGMENTS = Platform__iso_fopen(path_to_fragments, "r");
if (FRAGMENTS) {
char *p = Memory__I7_malloc(MAX_EXTENT_OF_FRAGMENTS, DOC_FRAGMENT_MREASON);
{
#line 1067 "inform7/Chapter 3/Index File Services.w"
int i = 0;
p[0] = 0;
while (TRUE) {
int c = Text__Reader__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 1058 "inform7/Chapter 3/Index File Services.w"
;
{
#line 1081 "inform7/Chapter 3/Index File Services.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 = 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 1059 "inform7/Chapter 3/Index File Services.w"
;
fclose(FRAGMENTS);
}
}
}
#line 1035 "inform7/Chapter 3/Index File Services.w"
;
fragments_loaded = TRUE;
}
documentation_ref *dr = 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 1106 "inform7/Chapter 3/Index File Services.w"
documentation_ref *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 1118 "inform7/Chapter 3/Index File Services.w"
if (problem_count == 0) {
LOG("Bad ref was <%s>. Known references are:\n", fn);
LOOP_OVER(dr, documentation_ref) {
LOG("<%s> = %s\n", Text__word_raw_text(dr->symbol), Text__word_raw_text(dr->section));
}
internal_error("Bad index documentation reference");
}
}
#line 1111 "inform7/Chapter 3/Index File Services.w"
;
return NULL;
}
#line 1133 "inform7/Chapter 3/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 1154 "inform7/Chapter 3/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 1179 "inform7/Chapter 3/Index File Services.w"
void Index__extra_div_open(int id, int indent, char *colour) {
INDEX("<div id=\"extra%d\" style=\"display: none;\">", id);
Formats__HTML__open_para(ifl, indent, "");
Formats__HTML__open_coloured_box(ifl, colour, ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
}
void Index__extra_div_close(char *colour) {
Formats__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);
Formats__HTML__open_para(ifl, indent, "");
}
void Index__extra_div_close_nested(void) {
INDEX("</div>\n");
}
#line 1202 "inform7/Chapter 3/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 1213 "inform7/Chapter 3/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 56 "inform7/Chapter 3/Lexicon Index.w"
lexicon_entry *lexicon_new_entry(int w1, int w2) {
lexicon_entry *lex = CREATE(lexicon_entry);
lex->w1 = w1; lex->w2 = w2;
lex->text_of_entry = Text__Words__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 71 "inform7/Chapter 3/Lexicon Index.w"
lexicon_entry *Index__Lexicon__new_entry_with_details(int w1, int w2, int pos,
word_assemblage wa, char *category, char *gloss) {
lexicon_entry *lex = lexicon_new_entry(w1, w2);
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 = lexicon_new_entry(-1, -1);
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 97 "inform7/Chapter 3/Lexicon Index.w"
void lexicon_copy_to_string(lexicon_entry *lex, char *str) {
if (lex->w1 >= 0) Text__print_raw_text_to_string(lex->w1, lex->w2, str);
else Text__Words__copy_to_string(&(lex->text_of_entry), str);
}
#line 108 "inform7/Chapter 3/Lexicon Index.w"
void Index__Lexicon__index(void) {
{
#line 136 "inform7/Chapter 3/Lexicon Index.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
int w1, w2;
Data__Instances__get_name(I, &w1, &w2, FALSE);
if (w1 >= 0) {
lexicon_entry *lex = lexicon_new_entry(w1, w2);
lex->part_of_speech = PROPER_NOUN_LEXE;
lex->category = "noun";
lex->entry_refers_to = STORE_POINTER_instance(I);
}
}
}
#line 109 "inform7/Chapter 3/Lexicon Index.w"
;
{
#line 153 "inform7/Chapter 3/Lexicon Index.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__lt(K, K_object)) {
int w1, w2;
Kinds__get_name(K, &w1, &w2, FALSE);
if (w1 >= 0) {
lexicon_entry *lex = lexicon_new_entry(w1, w2);
lex->part_of_speech = NOUN_LEXE;
lex->category = "noun";
lex->entry_refers_to = STORE_POINTER_kind(K);
}
}
}
#line 110 "inform7/Chapter 3/Lexicon Index.w"
;
{
#line 169 "inform7/Chapter 3/Lexicon Index.w"
lexicon_entry *lex;
adjectival_phrase *adj;
LOOP_OVER(adj, adjectival_phrase) {
int w1, w2;
Semantics__Adjectives__Meanings__get_text(adj, &w1, &w2, FALSE);
if (w1 >= 0) {
lex = lexicon_new_entry(w1, w2);
lex->part_of_speech = ADJECTIVAL_PHRASE_LEXE;
lex->category = "adjective";
lex->entry_refers_to = STORE_POINTER_adjectival_phrase(adj);
}
}
}
#line 111 "inform7/Chapter 3/Lexicon Index.w"
;
{
#line 187 "inform7/Chapter 3/Lexicon Index.w"
lexicon_entry *lex;
instance *qn;
LOOP_OVER_ENUMERATION_INSTANCES(qn) {
property *prn =
Kinds__get_coinciding_property(Data__Instances__kind(qn));
if ((prn) && (Properties__Valued__Conditions__of_what(prn))) continue;
int nw1, nw2;
Data__Instances__get_name(qn, &nw1, &nw2, FALSE);
lex = lexicon_new_entry(nw1, nw2);
lex->part_of_speech = ENUMERATED_CONSTANT_LEXE;
lex->category = "noun";
lex->entry_refers_to = STORE_POINTER_instance(qn);
}
}
#line 112 "inform7/Chapter 3/Lexicon Index.w"
;
{
#line 205 "inform7/Chapter 3/Lexicon Index.w"
Text__Languages__enter_lexicon(indefinite_article_NTM, MISCELLANEOUS_LEXE,
"indefinite article", NULL);
Text__Languages__enter_lexicon(definite_article_NTM, MISCELLANEOUS_LEXE,
"definite article", NULL);
Text__Languages__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 113 "inform7/Chapter 3/Lexicon Index.w"
;
{
#line 222 "inform7/Chapter 3/Lexicon Index.w"
lexicon_entry *lex;
LOOP_OVER(lex, lexicon_entry) {
int i;
char entry_text[MAX_TEXT_FOR_LEXICON_ENTRY];
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 115 "inform7/Chapter 3/Lexicon Index.w"
;
{
#line 237 "inform7/Chapter 3/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 116 "inform7/Chapter 3/Lexicon Index.w"
;
int common_nouns_only = FALSE;
Index__anchor("LEXICON");
{
#line 257 "inform7/Chapter 3/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 120 "inform7/Chapter 3/Lexicon Index.w"
;
{
#line 276 "inform7/Chapter 3/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) {
Formats__HTML__begin_html_table(ifl, NULL, TRUE, 0, 0, 0, 0, 0);
Formats__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)) Formats__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 323 "inform7/Chapter 3/Lexicon Index.w"
char entry_text[MAX_TEXT_FOR_LEXICON_ENTRY];
lexicon_copy_to_string(lex, entry_text);
Text__print_literal_string_to_file(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 297 "inform7/Chapter 3/Lexicon Index.w"
;
{
#line 341 "inform7/Chapter 3/Lexicon Index.w"
switch(lex->part_of_speech) {
case NOUN_LEXE: {
kind *K = RETRIEVE_POINTER_kind(lex->entry_refers_to);
if ((K) && (Kinds__get_documentation_reference(K)))
Index__doc_link(Kinds__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) && (lex->w1 >= 0))
Index__link(lex->w1);
}
#line 298 "inform7/Chapter 3/Lexicon Index.w"
;
switch(lex->part_of_speech) {
case ADJECTIVAL_PHRASE_LEXE:
{
#line 396 "inform7/Chapter 3/Lexicon Index.w"
int ac = 0, nc;
adjective_meaning *am;
adjectival_phrase *aph = RETRIEVE_POINTER_adjectival_phrase(lex->entry_refers_to);
{
#line 426 "inform7/Chapter 3/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 399 "inform7/Chapter 3/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);
Semantics__Adjectives__Meanings__print_to_index(am);
if (ac >= 1) INDEX("; ");
}
{
#line 433 "inform7/Chapter 3/Lexicon Index.w"
INDEX("</i>");
}
#line 408 "inform7/Chapter 3/Lexicon Index.w"
;
}
#line 302 "inform7/Chapter 3/Lexicon Index.w"
; break;
case ENUMERATED_CONSTANT_LEXE:
{
#line 414 "inform7/Chapter 3/Lexicon Index.w"
int w1, w2;
instance *qn = RETRIEVE_POINTER_instance(lex->entry_refers_to);
kind *K = Data__Instances__kind(qn);
{
#line 426 "inform7/Chapter 3/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 417 "inform7/Chapter 3/Lexicon Index.w"
;
INDEX(", value of ");
{
#line 433 "inform7/Chapter 3/Lexicon Index.w"
INDEX("</i>");
}
#line 419 "inform7/Chapter 3/Lexicon Index.w"
;
Kinds__get_name(K, &w1, &w2, FALSE);
Text__print_raw_text_to_stream(w1, w2, ifl);
}
#line 304 "inform7/Chapter 3/Lexicon Index.w"
; break;
case PROPER_NOUN_LEXE:
{
#line 380 "inform7/Chapter 3/Lexicon Index.w"
instance *I = RETRIEVE_POINTER_instance(lex->entry_refers_to);
kind *K = Data__Instances__kind(I);
if (Kinds__eq(K, K_thing) == FALSE) {
int w1, w2;
Kinds__get_name(K, &w1, &w2, FALSE);
if (w1 >= 0) {
{
#line 426 "inform7/Chapter 3/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 386 "inform7/Chapter 3/Lexicon Index.w"
;
Text__print_raw_text_to_stream(w1, w2, ifl);
{
#line 433 "inform7/Chapter 3/Lexicon Index.w"
INDEX("</i>");
}
#line 388 "inform7/Chapter 3/Lexicon Index.w"
;
}
}
}
#line 306 "inform7/Chapter 3/Lexicon Index.w"
; break;
case NOUN_LEXE:
{
#line 360 "inform7/Chapter 3/Lexicon Index.w"
kind *K = RETRIEVE_POINTER_kind(lex->entry_refers_to);
if (Kinds__lt(K, K_object)) {
int w1 = -1, w2 = -1;
K = Kinds__super(K);
Kinds__get_name(K, &w1, &w2, FALSE);
if (w1 >= 0) {
{
#line 426 "inform7/Chapter 3/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 366 "inform7/Chapter 3/Lexicon Index.w"
;
INDEX(", a kind of ");
{
#line 433 "inform7/Chapter 3/Lexicon Index.w"
INDEX("</i>");
}
#line 368 "inform7/Chapter 3/Lexicon Index.w"
;
Text__print_raw_text_to_stream(w1, w2, ifl);
}
} else {
{
#line 426 "inform7/Chapter 3/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 372 "inform7/Chapter 3/Lexicon Index.w"
;
INDEX(", a kind");
{
#line 433 "inform7/Chapter 3/Lexicon Index.w"
INDEX("</i>");
}
#line 374 "inform7/Chapter 3/Lexicon Index.w"
;
}
}
#line 308 "inform7/Chapter 3/Lexicon Index.w"
; break;
}
if (lex->gloss_note) INDEX(" <i>%s</i>", lex->gloss_note);
INDEX("</p>");
}
if (common_nouns_only) { Formats__HTML__end_html_row(ifl); Formats__HTML__end_html_table(ifl); }
}
#line 121 "inform7/Chapter 3/Lexicon Index.w"
;
}
#line 128 "inform7/Chapter 3/Lexicon Index.w"
void Index__Lexicon__index_common_nouns(void) {
int common_nouns_only = TRUE;
{
#line 276 "inform7/Chapter 3/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) {
Formats__HTML__begin_html_table(ifl, NULL, TRUE, 0, 0, 0, 0, 0);
Formats__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)) Formats__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 323 "inform7/Chapter 3/Lexicon Index.w"
char entry_text[MAX_TEXT_FOR_LEXICON_ENTRY];
lexicon_copy_to_string(lex, entry_text);
Text__print_literal_string_to_file(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 297 "inform7/Chapter 3/Lexicon Index.w"
;
{
#line 341 "inform7/Chapter 3/Lexicon Index.w"
switch(lex->part_of_speech) {
case NOUN_LEXE: {
kind *K = RETRIEVE_POINTER_kind(lex->entry_refers_to);
if ((K) && (Kinds__get_documentation_reference(K)))
Index__doc_link(Kinds__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) && (lex->w1 >= 0))
Index__link(lex->w1);
}
#line 298 "inform7/Chapter 3/Lexicon Index.w"
;
switch(lex->part_of_speech) {
case ADJECTIVAL_PHRASE_LEXE:
{
#line 396 "inform7/Chapter 3/Lexicon Index.w"
int ac = 0, nc;
adjective_meaning *am;
adjectival_phrase *aph = RETRIEVE_POINTER_adjectival_phrase(lex->entry_refers_to);
{
#line 426 "inform7/Chapter 3/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 399 "inform7/Chapter 3/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);
Semantics__Adjectives__Meanings__print_to_index(am);
if (ac >= 1) INDEX("; ");
}
{
#line 433 "inform7/Chapter 3/Lexicon Index.w"
INDEX("</i>");
}
#line 408 "inform7/Chapter 3/Lexicon Index.w"
;
}
#line 302 "inform7/Chapter 3/Lexicon Index.w"
; break;
case ENUMERATED_CONSTANT_LEXE:
{
#line 414 "inform7/Chapter 3/Lexicon Index.w"
int w1, w2;
instance *qn = RETRIEVE_POINTER_instance(lex->entry_refers_to);
kind *K = Data__Instances__kind(qn);
{
#line 426 "inform7/Chapter 3/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 417 "inform7/Chapter 3/Lexicon Index.w"
;
INDEX(", value of ");
{
#line 433 "inform7/Chapter 3/Lexicon Index.w"
INDEX("</i>");
}
#line 419 "inform7/Chapter 3/Lexicon Index.w"
;
Kinds__get_name(K, &w1, &w2, FALSE);
Text__print_raw_text_to_stream(w1, w2, ifl);
}
#line 304 "inform7/Chapter 3/Lexicon Index.w"
; break;
case PROPER_NOUN_LEXE:
{
#line 380 "inform7/Chapter 3/Lexicon Index.w"
instance *I = RETRIEVE_POINTER_instance(lex->entry_refers_to);
kind *K = Data__Instances__kind(I);
if (Kinds__eq(K, K_thing) == FALSE) {
int w1, w2;
Kinds__get_name(K, &w1, &w2, FALSE);
if (w1 >= 0) {
{
#line 426 "inform7/Chapter 3/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 386 "inform7/Chapter 3/Lexicon Index.w"
;
Text__print_raw_text_to_stream(w1, w2, ifl);
{
#line 433 "inform7/Chapter 3/Lexicon Index.w"
INDEX("</i>");
}
#line 388 "inform7/Chapter 3/Lexicon Index.w"
;
}
}
}
#line 306 "inform7/Chapter 3/Lexicon Index.w"
; break;
case NOUN_LEXE:
{
#line 360 "inform7/Chapter 3/Lexicon Index.w"
kind *K = RETRIEVE_POINTER_kind(lex->entry_refers_to);
if (Kinds__lt(K, K_object)) {
int w1 = -1, w2 = -1;
K = Kinds__super(K);
Kinds__get_name(K, &w1, &w2, FALSE);
if (w1 >= 0) {
{
#line 426 "inform7/Chapter 3/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 366 "inform7/Chapter 3/Lexicon Index.w"
;
INDEX(", a kind of ");
{
#line 433 "inform7/Chapter 3/Lexicon Index.w"
INDEX("</i>");
}
#line 368 "inform7/Chapter 3/Lexicon Index.w"
;
Text__print_raw_text_to_stream(w1, w2, ifl);
}
} else {
{
#line 426 "inform7/Chapter 3/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 372 "inform7/Chapter 3/Lexicon Index.w"
;
INDEX(", a kind");
{
#line 433 "inform7/Chapter 3/Lexicon Index.w"
INDEX("</i>");
}
#line 374 "inform7/Chapter 3/Lexicon Index.w"
;
}
}
#line 308 "inform7/Chapter 3/Lexicon Index.w"
; break;
}
if (lex->gloss_note) INDEX(" <i>%s</i>", lex->gloss_note);
INDEX("</p>");
}
if (common_nouns_only) { Formats__HTML__end_html_row(ifl); Formats__HTML__end_html_table(ifl); }
}
#line 130 "inform7/Chapter 3/Lexicon Index.w"
;
}
#line 439 "inform7/Chapter 3/Lexicon Index.w"
void Index__Lexicon__index_verbs(void) {
INDEX("<p></p>"); /* for spacing */
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 == 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 */
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 == PREP_LEXE) INDEX("To be <b>%s</b>", entry_text);
else INDEX("To be able to <b>%s</b>", entry_text);
if (lex->w1 >= 0) Index__link(lex->w1);
Semantics__VerbUsage__tabulate_meaning(lex);
INDEX("</p>");
Semantics__VerbUsage__tabulate(lex, IS_TENSE, "present");
Semantics__VerbUsage__tabulate(lex, WAS_TENSE, "past");
Semantics__VerbUsage__tabulate(lex, HASBEEN_TENSE, "present perfect");
Semantics__VerbUsage__tabulate(lex, HADBEEN_TENSE, "past perfect");
}
}
#line 468 "inform7/Chapter 3/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)
&& (Text__file_of_origin(lex->verb_defined_at->word_ref1) == sf)) {
char entry_text[MAX_TEXT_FOR_LEXICON_ENTRY];
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__Entries__new_str("verb", ef, entry_text);
}
if (verb_count > 0) WRITE("<p>");
}
#line 30 "inform7/Chapter 4/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 Problems__Progress__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;
STREAM_WRITE(STDERR, "++ %d%% (%s)\n", pc, progress_stage_name[stage]);
STREAM_FLUSH(STDERR);
last_progress_pc = pc;
}
void Problems__Progress__final_state_of_progress_bar(void) {
if (show_progress_indicator) {
STREAM_WRITE(STDERR, "++ 100%% (Finishing work)\n");
STREAM_FLUSH(STDERR);
}
}
#line 61 "inform7/Chapter 4/Progress Percentages.w"
STREAM *Problems__Progress__begin_outcome(void) {
if (show_progress_indicator == FALSE) return NULL;
STREAM_WRITE(STDERR, "++ Ended: ");
return STDERR;
}
void Problems__Progress__end_outcome(void) {
if (show_progress_indicator == FALSE) return;
STREAM_WRITE(STDERR, "\n");
STREAM_FLUSH(STDERR);
}
#line 11 "inform7/Chapter 4/Problems, Level 0.w"
void Problems__Fatal__issue(char *message) {
STREAM_WRITE(STDERR, message);
STREAM_WRITE(STDERR, "\n");
STREAM_FLUSH(STDERR);
exit(2);
}
void Problems__Fatal__issue2(char *message, char *fn) {
STREAM_WRITE(STDERR, message);
STREAM_WRITE(STDERR, "\nOffending filename: <%s>\n", fn);
STREAM_FLUSH(STDERR);
exit(2);
}
#line 33 "inform7/Chapter 4/Problems, Level 0.w"
int crash_on_all_errors = FALSE;
int crash_on_internal_errors = FALSE;
void Problems__Fatal__force_crash(void) {
STREAM_FLUSH(STDOUT);
STREAM_FLUSH(dl);
STREAM_WRITE(STDERR,
"*** Intentionally crashing to force stack backtrace to console logs ***\n");
STREAM_FLUSH(STDERR);
parse_node *PN = NULL; Parser__Nodes__log_subtree(PN->next, 1);
exit(1);
}
#line 17 "inform7/Chapter 4/Problems, Level 1.w"
char problem_buffer[PROBLEM_BUFFER_LENGTH];
#line 33 "inform7/Chapter 4/Problems, Level 1.w"
void Problems__copy_text_into_problem_buffer(int w1, int w2) {
if (w2 > w1 + QUOTATION_TOLERANCE_LIMIT) w2 = w1 + QUOTATION_TOLERANCE_LIMIT - 1;
Text__print_modest_sized_text_to_string(w1, w2, PBUFF);
}
#line 41 "inform7/Chapter 4/Problems, Level 1.w"
parse_node *redirected_sentence = NULL;
parse_node *redirected_to_A = NULL, *redirected_to_B = NULL;
void Problems__redirect_problem_sentence(parse_node *from, parse_node *A, parse_node *B) {
redirected_sentence = from; redirected_to_A = A; redirected_to_B = B;
}
#line 53 "inform7/Chapter 4/Problems, Level 1.w"
void Problems__copy_source_reference_into_problem_buffer(int w1, int w2) {
char *filename, *paraphrase;
if (w1 < 0) { sprintf(PBUFF, "<no text>"); return; }
source_file *referred = Text__file_of_origin(w1);
if (referred) {
filename = Text__Reader__sf_get_filename(referred);
if (bundle_name &&
(strncmp(filename, bundle_name, (size_t) Platform__strlen(bundle_name)) == 0))
filename += Platform__strlen(bundle_name) + 1;
} else filename = "(no file)";
sprintf(PBUFF, "'");
Problems__copy_text_into_problem_buffer(w1, w2);
paraphrase = "source text";
extension_file *ef = Text__Reader__sf_get_extension_corresponding(referred);
if (ef) {
extension_identifier *eid = Extensions__Files__get_eid(ef);
paraphrase = filename;
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, filename,
SOURCE_REF_CHAR, Text__word_location(w1).line_number,
SOURCE_REF_CHAR);
if ((redirected_sentence) &&
(redirected_to_A) &&
(redirected_to_B) &&
(redirected_sentence->word_ref1 == w1) &&
(redirected_sentence->word_ref2 == w2)) {
sprintf(PBUFF, " (which asserts that ");
Problems__copy_source_reference_into_problem_buffer(
redirected_to_A->word_ref1, redirected_to_A->word_ref2);
sprintf(PBUFF, " is/are ");
Problems__copy_source_reference_into_problem_buffer(
redirected_to_B->word_ref1, redirected_to_B->word_ref2);
sprintf(PBUFF, ")");
}
}
#line 99 "inform7/Chapter 4/Problems, Level 1.w"
int is_problem_buffer_whitespace(char c) {
if ((c == ' ') || (c == '\t') || (c == '\n')) return TRUE;
return FALSE;
}
#line 113 "inform7/Chapter 4/Problems, Level 1.w"
int problem_count_at_last_in = 1;
void 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 140 "inform7/Chapter 4/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=\"tightin3\">"); else WRITE(" ");
i+=4; continue;
}
}
#line 121 "inform7/Chapter 4/Problems, Level 1.w"
;
{
#line 180 "inform7/Chapter 4/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 122 "inform7/Chapter 4/Problems, Level 1.w"
;
if ((html_flag == FALSE) && (c == SOURCE_REF_CHAR))
{
#line 219 "inform7/Chapter 4/Problems, Level 1.w"
WRITE("("); line_width++;
while (problem_buffer[++i] != SOURCE_REF_CHAR)
{
#line 229 "inform7/Chapter 4/Problems, Level 1.w"
c = problem_buffer[i];
if (is_problem_buffer_whitespace(c)) { /* this starts a run of whitespace */
int l = i; while (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) Formats__HTML__html_char_out(OUT, ' ');
else
{
#line 248 "inform7/Chapter 4/Problems, Level 1.w"
int word_width = 0;
while ((!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 235 "inform7/Chapter 4/Problems, Level 1.w"
;
} else {
line_width++;
if (html_flag) Formats__HTML__html_char_out(OUT, c);
else if ((c != SOURCE_REF_CHAR) && (c != FORCE_NEW_PARA_CHAR)) WRITE("%c", c);
}
}
#line 220 "inform7/Chapter 4/Problems, Level 1.w"
;
while (problem_buffer[++i] != SOURCE_REF_CHAR) ;
WRITE(", line "); line_width += 7;
while (problem_buffer[++i] != SOURCE_REF_CHAR)
{
#line 229 "inform7/Chapter 4/Problems, Level 1.w"
c = problem_buffer[i];
if (is_problem_buffer_whitespace(c)) { /* this starts a run of whitespace */
int l = i; while (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) Formats__HTML__html_char_out(OUT, ' ');
else
{
#line 248 "inform7/Chapter 4/Problems, Level 1.w"
int word_width = 0;
while ((!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 235 "inform7/Chapter 4/Problems, Level 1.w"
;
} else {
line_width++;
if (html_flag) Formats__HTML__html_char_out(OUT, c);
else if ((c != SOURCE_REF_CHAR) && (c != FORCE_NEW_PARA_CHAR)) WRITE("%c", c);
}
}
#line 223 "inform7/Chapter 4/Problems, Level 1.w"
;
WRITE(")"); line_width++;
}
#line 124 "inform7/Chapter 4/Problems, Level 1.w"
else
{
#line 229 "inform7/Chapter 4/Problems, Level 1.w"
c = problem_buffer[i];
if (is_problem_buffer_whitespace(c)) { /* this starts a run of whitespace */
int l = i; while (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) Formats__HTML__html_char_out(OUT, ' ');
else
{
#line 248 "inform7/Chapter 4/Problems, Level 1.w"
int word_width = 0;
while ((!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 235 "inform7/Chapter 4/Problems, Level 1.w"
;
} else {
line_width++;
if (html_flag) Formats__HTML__html_char_out(OUT, c);
else if ((c != SOURCE_REF_CHAR) && (c != FORCE_NEW_PARA_CHAR)) WRITE("%c", c);
}
}
#line 125 "inform7/Chapter 4/Problems, Level 1.w"
;
}
if (html_flag) WRITE("</p>");
WRITE("\n");
}
#line 265 "inform7/Chapter 4/Problems, Level 1.w"
int telemetry_recording = FALSE;
void Problems__output_problem_buffer(int indentation) {
if (probl == NULL) {
output_problem_buffer_to(problems_file, indentation);
STREAM_WRITE(problems_file, "\n");
output_problem_buffer_to(STDERR, indentation);
STREAM_FLUSH(STDERR);
STREAM_WRITE(dl, "\n");
output_problem_buffer_to(dl, indentation);
STREAM_WRITE(dl, "\n");
if (telemetry_recording) {
STREAM_WRITE(telmy, "\n");
output_problem_buffer_to(telmy, indentation);
STREAM_WRITE(telmy, "\n");
}
} else output_problem_buffer_to(probl, indentation);
}
#line 26 "inform7/Chapter 4/Problems, Level 2.w"
parse_node *problem_headings[NO_HEADING_LEVELS];
void Problems__empty_all_headings(void) {
Problems__empty_headings(0);
}
void Problems__empty_headings(int from_level) {
int i;
for (i=from_level; i<NO_HEADING_LEVELS; i++) problem_headings[i] = NULL;
}
#line 48 "inform7/Chapter 4/Problems, Level 2.w"
void find_headings_at(parse_node *sentence) {
parse_node *p;
Problems__empty_headings(0);
if (sentence == NULL) return;
for (p = tree_root->down; p != NULL; p = p->next) {
if (Parser__Nodes__contains(p, sentence)) return;
if (Parser__Nodes__type(p) == HEADING_NT) {
problem_headings[Parser__Nodes__int_annotation(p, heading_level_ANNOT)] = p;
Problems__empty_headings(Parser__Nodes__int_annotation(p, heading_level_ANNOT) + 1);
}
if (Parser__Nodes__type(p) == ENDHERE_NT) {
Problems__empty_all_headings();
}
}
}
#line 74 "inform7/Chapter 4/Problems, Level 2.w"
parse_node *last_problem_headings[NO_HEADING_LEVELS];
#line 86 "inform7/Chapter 4/Problems, Level 2.w"
int do_not_locate_problems = FALSE;
void show_problem_location(void) {
int i, f = FALSE;
if (problem_count == 0) {
if (internal_error_thrown)
Formats__HTML__html_outcome_image(problems_file, "ni_failed_badly", "Failed");
else
Formats__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;
find_headings_at(current_sentence);
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 114 "inform7/Chapter 4/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 = Text__file_of_origin(problem_headings[i]->word_ref1);
if (f) strcat(problem_buffer, ", ");
else strcat(problem_buffer, " ");
f = TRUE;
Problems__copy_text_into_problem_buffer(
problem_headings[i]->word_ref1, problem_headings[i]->word_ref2);
}
if (f == FALSE) strcat(problem_buffer, " the main source text");
if (pos) {
extension_file *ef = Text__Reader__sf_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__output_problem_buffer(0);
}
#line 103 "inform7/Chapter 4/Problems, Level 2.w"
;
break;
}
for (i=0; i<NO_HEADING_LEVELS; i++) last_problem_headings[i] = problem_headings[i];
}
#line 163 "inform7/Chapter 4/Problems, Level 2.w"
problem_quotation problem_quotations[10];
#line 173 "inform7/Chapter 4/Problems, Level 2.w"
void 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].range_quoted_w1 = -1;
problem_quotations[t].range_quoted_w2 = -1;
}
void problem_quote_textual(int t, char type, int w1, int w2) {
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].range_quoted_w1 = w1;
problem_quotations[t].range_quoted_w2 = w2;
}
#line 193 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_source(int t, parse_node *p) {
if (p == NULL) problem_quote_textual(t, 'S', -1, -1);
else problem_quote_textual(t, 'S', p->word_ref1, p->word_ref2);
}
void Problems__quote_source_eliding_begin(int t, parse_node *p) {
if (p == NULL) problem_quote_textual(t, 'S', -1, -1);
else {
int w1 = p->word_ref1, w2 = p->word_ref2;
if (parse_nt_against_word_range(phrase_beginning_block_NTM, w1, w2, NULL, NULL)) GET_RW(phrase_beginning_block_NTM, 1, w1, w2);
problem_quote_textual(t, 'S', w1, w2);
}
}
void Problems__quote_words(int t, int w1, int w2) { problem_quote_textual(t, 'W', w1, w2); }
void Problems__quote_words_as_source(int t, int w1, int w2) { problem_quote_textual(t, 'S', w1, w2); }
#line 211 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_relation(int t, binary_predicate *bp) { problem_quote(t, 'B', (void *) bp); }
void Problems__quote_extension(int t, extension_file *ef) { problem_quote(t, 'E', (void *) ef); }
void Problems__quote_phrase(int t, phrase *p) { problem_quote(t, 'H', (void *) p); }
void Problems__quote_invocation(int t, invocation *inv) { problem_quote(t, 'I', (void *) inv); }
void Problems__quote_number(int t, int *num) { problem_quote(t, 'N', (void *) num); }
void Problems__quote_object(int t, instance *I) { problem_quote(t, 'O', (void *) I); }
void Problems__quote_subject(int t, inference_subject *infs) {
if (infs == NULL) { Problems__quote_text(t, "something"); return; }
int w1 = -1, w2 = -1;
World__Subjects__get_name_text(infs, &w1, &w2);
if (w1 >= 0) { Problems__quote_words(t, w1, w2); return; }
instance *I = World__Subjects__as_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, Data__Tables__get_headline(tab));
}
void Problems__quote_property(int t, property *p) { problem_quote(t, 'P', (void *) p); }
void Problems__quote_text(int t, char *message) { problem_quote(t, 'T', (void *) message); }
void Problems__quote_wa(int t, word_assemblage *wa) { problem_quote(t, 'A', (void *) wa); }
void Problems__quote_spec(int t, specification *spec) { problem_quote(t, 'Y', (void *) spec); }
void Problems__quote_extension_id(int t, extension_identifier *eid) { problem_quote(t, 'X', (void *) eid); }
#line 240 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_kind_of(int t, specification *spec) {
kind *K = Specifications__Conditions__get_described_kind(spec);
if ((K) && (Kinds__lt(K, K_object))) {
Problems__quote_kind(t, K); return; }
if (Specifications__Conditions__get_described_instance(spec)) {
Problems__quote_kind(t, Data__Instances__kind(Specifications__Conditions__get_described_instance(spec))); return; }
if (Specifications__Values__is_CONSTANT_object(spec)) {
if (Specifications__test_flag(spec, SELF_OBJECT_SPFLAG)) {
Problems__quote_text(t, "implicit object"); /* this is probably never seen, but just in case */
return;
} else if (Specifications__test_flag(spec, NOTHING_OBJECT_SPFLAG)) {
Problems__quote_text(t, "the 'nothing' non-object"); /* whereas this can certainly happen */
return;
} else if (Specifications__is_actual(spec)) {
instance *I = instance_spec_to_instance(spec);
Problems__quote_kind(t, Data__Instances__kind(I));
return;
}
}
if ((spec) && (Specifications__species_is(spec, CONSTANT_SPC)))
spec = Specifications__Values__new_generic_CONSTANT(Specifications__get_kind(spec));
Problems__quote_spec(t, spec);
}
#line 267 "inform7/Chapter 4/Problems, Level 2.w"
void Problems__quote_kind(int t, kind *K) {
if ((K == NULL) || (Kinds__eq(K, K_nil))) Problems__quote_text(t, "nothing");
else Problems__quote_spec(t, Specifications__Values__new_generic_CONSTANT(K));
}
#line 280 "inform7/Chapter 4/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 292 "inform7/Chapter 4/Problems, Level 2.w"
char *explanations[PATIENCE_EXHAUSTION_POINT];
int no_explanations = 0;
int 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 316 "inform7/Chapter 4/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) {
shorten_problem_message = FALSE;
} else {
show_problem_location();
problem_count++;
strcpy(problem_buffer, ">--> ");
shorten_problem_message = 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) Data__Strings__append_text_substitution_proviso();
Problems__output_problem_buffer(1);
Problems__problem_documentation_links(problems_file);
if (crash_on_all_errors) Problems__Fatal__force_crash();
}
#line 361 "inform7/Chapter 4/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 394 "inform7/Chapter 4/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 414 "inform7/Chapter 4/Problems, Level 2.w"
property *pr;
switch(problem_quotations[t].quotation_type) {
/* Text range-based quotations */
case 'S': Problems__copy_source_reference_into_problem_buffer(
problem_quotations[t].range_quoted_w1, problem_quotations[t].range_quoted_w2);
break;
case 'W': Problems__copy_text_into_problem_buffer(
problem_quotations[t].range_quoted_w1, problem_quotations[t].range_quoted_w2);
break;
/* Binary structure-based quotations */
case 'A':
{
#line 457 "inform7/Chapter 4/Problems, Level 2.w"
word_assemblage *wa = (word_assemblage *) problem_quotations[t].structure_quoted;
TEMPORARY_STREAM;
Text__Words__copy_to_stream(TEMP, wa);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 426 "inform7/Chapter 4/Problems, Level 2.w"
;
break;
case 'B':
{
#line 466 "inform7/Chapter 4/Problems, Level 2.w"
binary_predicate *bp = (binary_predicate *) problem_quotations[t].structure_quoted;
TEMPORARY_STREAM;
Semantics__BPs__describe_for_problems(TEMP, bp);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 428 "inform7/Chapter 4/Problems, Level 2.w"
;
break;
case 'E':
{
#line 493 "inform7/Chapter 4/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 430 "inform7/Chapter 4/Problems, Level 2.w"
;
break;
case 'H':
{
#line 475 "inform7/Chapter 4/Problems, Level 2.w"
phrase *ph = (phrase *) (problem_quotations[t].structure_quoted);
TEMPORARY_STREAM;
Code__Phrases__write_HTML_representation(TEMP, ph, INDEX_PHRASE_FORMAT);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 432 "inform7/Chapter 4/Problems, Level 2.w"
;
break;
case 'I':
{
#line 484 "inform7/Chapter 4/Problems, Level 2.w"
invocation *inv = (invocation *) (problem_quotations[t].structure_quoted);
TEMPORARY_STREAM;
Code__Phrases__TypeData__inv_write_HTML_representation(TEMP, inv);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 434 "inform7/Chapter 4/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 526 "inform7/Chapter 4/Problems, Level 2.w"
instance *I = (instance *) problem_quotations[t].structure_quoted;
if (I == NULL) break;
int w1, w2;
Data__Instances__get_name(I, &w1, &w2, FALSE);
if (w1 >= 0)
Problems__copy_text_into_problem_buffer(w1, w2);
else {
strcat(problem_buffer, "nameless ");
kind *k = Data__Instances__kind(I);
int kw1 = -1, kw2 = -1;
Kinds__get_name(k, &kw1, &kw2, FALSE);
if (kw1 >= 0) Problems__copy_text_into_problem_buffer(kw1, kw2);
else strcat(problem_buffer, "thing");
parse_node *from = Data__Instances__get_creating_sentence(I);
if (from) {
strcat(problem_buffer, " created in the sentence ");
Problems__copy_source_reference_into_problem_buffer(from->word_ref1, from->word_ref2);
}
}
}
#line 440 "inform7/Chapter 4/Problems, Level 2.w"
;
break;
case 'P': pr = (property *) problem_quotations[t].structure_quoted;
Problems__copy_text_into_problem_buffer(pr->word_ref1, pr->word_ref2);
break;
case 'T': strcat(problem_buffer, (char *) (problem_quotations[t].structure_quoted));
break;
case 'X':
{
#line 511 "inform7/Chapter 4/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 447 "inform7/Chapter 4/Problems, Level 2.w"
;
break;
case 'Y':
{
#line 502 "inform7/Chapter 4/Problems, Level 2.w"
specification *spec = (specification *) problem_quotations[t].structure_quoted;
TEMPORARY_STREAM;
Specifications__write_out_in_English(TEMP, spec);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 449 "inform7/Chapter 4/Problems, Level 2.w"
;
break;
default: internal_error("unknown error token type");
}
}
#line 403 "inform7/Chapter 4/Problems, Level 2.w"
;
continue;
}
}
len = Platform__strlen(problem_buffer);
problem_buffer[len] = message[i]; problem_buffer[len+1] = 0;
}
#line 382 "inform7/Chapter 4/Problems, Level 2.w"
;
}
}
#line 556 "inform7/Chapter 4/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 591 "inform7/Chapter 4/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 566 "inform7/Chapter 4/Problems, Level 2.w"
else
{
#line 607 "inform7/Chapter 4/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.)");
Formats__HTML__outcome_image_tail(problems_file);
STREAM *STATUS = Problems__Progress__begin_outcome();
if (STATUS) {
STREAM_WRITE(STATUS, "Translation failed: %d problem%s found",
problem_count, (problem_count==1)?"":"s");
Problems__Progress__end_outcome();
}
}
#line 567 "inform7/Chapter 4/Problems, Level 2.w"
;
Problems__issue_problem_end();
probl = NULL;
} else {
int rooms, things;
Formats__HTML__html_outcome_image(problems_file, "ni_succeeded", "Succeeded");
Plugins__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 = Text__Reader__sf_total_word_count(FIRST_OBJECT(source_file));
Problems__quote_number(5, &total_words);
{
#line 640 "inform7/Chapter 4/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();
Formats__HTML__outcome_image_tail(problems_file);
if (telemetry_recording) {
Log__Telemetry__ensure_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();
STREAM_WRITE(telmy, "\n");
}
probl = STDOUT;
STREAM_WRITE(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;
Problems__Progress__final_state_of_progress_bar();
STREAM *STATUS = Problems__Progress__begin_outcome();
if (STATUS) {
STREAM_WRITE(STATUS, "Translation succeeded: %d room%s, %d thing%s",
rooms, (rooms==1)?"":"s",
things, (things==1)?"":"s");
Problems__Progress__end_outcome();
}
}
#line 580 "inform7/Chapter 4/Problems, Level 2.w"
;
problem_count = 0;
}
}
#line 31 "inform7/Chapter 4/Problems, Level 3.w"
void internal_error_end(void) {
Problems__issue_problem_end();
Log__mlc_backtrace();
Problems__write_reports(TRUE);
if (crash_on_internal_errors) Problems__Fatal__force_crash();
exit(1);
}
#line 47 "inform7/Chapter 4/Problems, Level 3.w"
void internal_error_fn(char *p, char *filename, int linenum) {
internal_error_thrown = TRUE;
if (current_sentence == NULL) {
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.");
internal_error_end();
}
void 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.");
internal_error_end();
}
#line 86 "inform7/Chapter 4/Problems, Level 3.w"
void nodal_error_fn(parse_node *pn, char *p, char *filename, int linenum) {
LOG("Internal nodal error at:\n");
Parser__Nodes__log_subtree(pn, 1);
internal_error_fn(p, filename, linenum);
}
#line 95 "inform7/Chapter 4/Problems, Level 3.w"
void nodal_check(parse_node *pn, int node_type_required, char *filename, int linenum) {
char internal_message[128];
if (pn == NULL) {
sprintf(internal_message, "NULL node found where type %s expected",
Parser__Nodes__Types__get_name(node_type_required));
internal_error_tu_fn(internal_message, filename, linenum);
}
if (Parser__Nodes__type(pn) == node_type_required) return;
if ((Parser__Nodes__type(pn) < 1) || (Parser__Nodes__type(pn) > HIGHEST_NODE_TYPE)) {
sprintf(internal_message, "Node with corrupt type found where type %s expected",
Parser__Nodes__Types__get_name(node_type_required));
internal_error_tu_fn(internal_message, filename, linenum);
}
sprintf(internal_message, "Node of type %s found where type %s expected",
Parser__Nodes__Types__get_name(Parser__Nodes__type(pn)),
Parser__Nodes__Types__get_name(node_type_required));
nodal_error_fn(pn, internal_message, filename, linenum);
}
#line 119 "inform7/Chapter 4/Problems, Level 3.w"
void internal_error_on_node_type_fn(parse_node *pn, char *filename,
int linenum) {
char internal_message[128];
if (pn == NULL)
internal_error_tu_fn("Unexpected NULL node found", filename, linenum);
if ((Parser__Nodes__type(pn) < 1) || (Parser__Nodes__type(pn) > HIGHEST_NODE_TYPE))
internal_error_tu_fn("Node found with corrupt type", filename, linenum);
sprintf(internal_message, "Unexpectedly found node of type %s",
Parser__Nodes__Types__get_name(Parser__Nodes__type(pn)));
nodal_error_fn(pn, internal_message, filename, linenum);
}
#line 136 "inform7/Chapter 4/Problems, Level 3.w"
meaning_list *latest_s_subtree = NULL;
void Problems__s_subtree_error_set_position(meaning_list *ml) {
latest_s_subtree = ml;
}
void Problems__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$m", latest_s_subtree);
internal_error(internal_message);
}
#line 202 "inform7/Chapter 4/Problems, Level 3.w"
char *sigil_of_latest_problem = NULL;
void Problems__problem_documentation_links(OUTPUT_STREAM) {
if (sigil_of_latest_problem == NULL) return;
char *chap = NULL, *sec = NULL;
char *leaf = Index__DocReferences__link_if_possible_once(sigil_of_latest_problem, &chap, &sec);
if (leaf) {
Formats__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) {
STREAM_WRITE(telmy, "See the manual: %s > %s\n\n", chap, sec);
}
}
sigil_of_latest_problem = NULL;
}
#line 230 "inform7/Chapter 4/Problems, Level 3.w"
int echo_problem_message_sigils = FALSE;
#line 236 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__handmade_problem(SIGIL_ARGUMENTS) {
ACT_ON_SIGIL
Problems__issue_problem_begin("");
}
#line 246 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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__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 281 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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 302 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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;
}
#line 318 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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 331 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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 347 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__sentence_in_detail_problem(SIGIL_ARGUMENTS,
int w1, int w2, 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_words(4, w1, w2);
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 364 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__negative_sentence_problem(SIGIL_ARGUMENTS) {
Problems__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 384 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__assertion_problem(SIGIL_ARGUMENTS, char *message, char *explanation) {
int i, w1, w2, rather_than_w1 = -1, rather_than_w2 = -1;
ACT_ON_SIGIL
if ((current_sentence == NULL) || (current_sentence->down == NULL) ||
(Parser__Nodes__type(current_sentence->down) != VERB_NT)) {
LOG("(Assertion error reverting to sentence error.)\n");
Problems__sentence_problem(PASS_SIGIL, message, explanation);
return;
}
w1 = current_sentence->word_ref1;
w2 = current_sentence->word_ref2;
LOG("(Assertion error: looking for alternative verbs in <$W>.)\n", w1, w2);
for (i=w1+1; i<=w2-1; i++)
if ((i != current_sentence->down->word_ref1) &&
(Text__unexpectedly_upper_case(i) == FALSE)) {
int j = parse_nt_against_word_range(general_verb_NTM, i, w2, NULL, NULL);
if (j > 0) { rather_than_w1 = i; rather_than_w2 = 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 (rather_than_w1 >= 0) {
Problems__quote_words(4, current_sentence->down->word_ref1,
current_sentence->down->word_ref2);
Problems__quote_words(5, rather_than_w1, rather_than_w2);
Problems__issue_problem_segment( /* see also C2AmbiguousVerb */
" %P(It may help to know that I am reading the primary verb here "
"as '%4', not '%5'.)");
}
Problems__diagnose_further();
Problems__issue_problem_end();
}
void Problems__diagnose_further(void) {
if (current_sentence == NULL) return;
int w1 = current_sentence->word_ref1, w2 = current_sentence->word_ref2;
if (w1 < 0) return;
int sqc = 0;
for (int i=w1; i<=w2; i++) 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 = Parser__Sentences__detect_control_structure(w1, w2);
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 449 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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__adjective_problem(SIGIL_ARGUMENTS, int ix1, int ix2, int d1, int d2,
char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_words(1, ix1, ix2);
Problems__quote_words(2, d1, d2);
Problems__quote_text(3, message);
Problems__quote_text(4, explanation);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment("You defined an adjective by '%1' intending that "
"it would apply to '%2': %Sagain, %%%Lbut %%%3%|, %4");
Problems__issue_problem_end();
}
#line 478 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__two_sentences_problem(SIGIL_ARGUMENTS, parse_node *other_sentence,
char *message, char *explanation) {
ACT_ON_SIGIL
if (current_sentence == other_sentence) {
Problems__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 499 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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 ((B->word_ref1 != A->word_ref1) || (B->word_ref2 != A->word_ref2))
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__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 ((B->word_ref1 != A->word_ref1) || (B->word_ref2 != A->word_ref2))
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 537 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__table_problem(SIGIL_ARGUMENTS, table *t, table_column *tc, parse_node *data,
char *message) {
ACT_ON_SIGIL
Problems__quote_table(1, t);
if (tc) Problems__quote_words(2, tc->word_ref1, tc->word_ref2);
if (data) Problems__quote_source(3, data);
Problems__issue_problem_begin("");
Problems__issue_problem_segment(message);
Problems__issue_problem_end();
}
#line 552 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__equation_problem(SIGIL_ARGUMENTS, equation *eqn, char *p, char *text) {
ACT_ON_SIGIL
char plenty[1000];
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, eqn->word_ref1, eqn->word_ref2);
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__equation_symbol_problem(SIGIL_ARGUMENTS, equation *eqn, int w1, int w2, char *text) {
ACT_ON_SIGIL
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
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 579 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__inline_problem(SIGIL_ARGUMENTS, phrase *ph, char *definition,
char *message) {
ACT_ON_SIGIL
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, definition);
int w1 = -1, w2 = -1;
Code__Phrases__Usage__get_preamble_text(&(ph->usage_data), &w1, &w2);
Problems__quote_words_as_source(3, w1, w2);
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 601 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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_words(2, tck->ew1, tck->ew2);
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 623 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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__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__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 664 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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);
int w1, w2;
World__Subjects__get_name_text(subj, &w1, &w2);
if (w1 >= 0) {
Problems__quote_source(4, Parser__Sentences__NPs__new_raw(w1, w2));
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 693 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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 712 "inform7/Chapter 4/Problems, Level 3.w"
void 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 726 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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 742 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__release_problem(SIGIL_ARGUMENTS, char *message, char *filename) {
ACT_ON_SIGIL
Problems__quote_text(1, message);
Problems__quote_text(2, filename);
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__release_problem_at_sentence(SIGIL_ARGUMENTS, char *message, char *filename) {
ACT_ON_SIGIL
Problems__quote_text(1, message);
Problems__quote_text(2, filename);
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 768 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__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__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_words(3, vw1, 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 794 "inform7/Chapter 4/Problems, Level 3.w"
void Problems__start_problems_report(void) {
char *fn = Files__Filenames__build(PROBLEM_LOG_LEAFNAME);
if (STREAM_OPEN_TO_FILE(problems_file, fn, UTF8_ENC) == FALSE)
Problems__Fatal__issue2("Can't open problem log", fn);
Formats__HTML__html_header(problems_file, "Translating the Source", NULL, NULL);
}
void Problems__issue_problems_banner(OUTPUT_STREAM, char *verdict) {
WRITE("<table cellspacing=\"3\" border=\"0\" width=\"100%%\">"
"<tr id=\"surround0\"><td style=\"width:100%%\">\n");
WRITE("<div class=\"headingbox%s\">\n", verdict);
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);
WRITE("</div></td>\n");
WRITE("</tr></table>");
}
#line 272 "inform7/Chapter 4/Debugging Log.w"
void Log__open(void) {
char *fn = Files__Filenames__build(DEBUG_LOG_LEAFNAME);
if (STREAM_OPEN_TO_FILE(debug_log_file, fn, ISO_ENC) == FALSE)
Problems__Fatal__issue2("Can't open debug log", fn);
dl = debug_log_file;
LOG("Debugging log of %s\n", NI_VERSION);
Problems__start_problems_report();
}
void Log__close(void) {
show_debugging_contents();
STREAM_CLOSE(debug_log_file); dl = NULL;
if (telmy) {
STREAM_WRITE(telmy, "End of telemetry for this run.\n");
STREAM_CLOSE(telmy); telmy = NULL;
}
Formats__HTML__html_footer(problems_file); STREAM_CLOSE(problems_file);
}
#line 299 "inform7/Chapter 4/Debugging Log.w"
int attempts_to_open_telemetry = 0;
void Log__Telemetry__ensure_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__issue2("Can't open telemetry file", filename_of_telemetry);
telmy = telemetry_file;
STREAM_WRITE(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;
STREAM_WRITE(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__Telemetry__write_note(char *m) {
Log__Telemetry__ensure_file();
STREAM_WRITE(telmy, "The user says:\n\n%s\n\n", m);
}
#line 325 "inform7/Chapter 4/Debugging Log.w"
int options_file_w1 = -1, options_file_w2 = -1;
void Log__read_further_mandatory_text(void) {
FILE *FMAN = Platform__iso_fopen(filename_of_options, "r");
if (FMAN == NULL) return;
char line_buffer[300];
options_file_w1 = lexer_wordcount;
while (TRUE) {
int len = Files__truncated_iso_fgets(FMAN, line_buffer, 255);
if (len < 0) break;
strcat(line_buffer, "\n");
int w1 = lexer_wordcount, w2;
Text__feed_into_lexer(line_buffer, FALSE, NULL);
w2 = lexer_wordcount - 2;
if (parse_nt_against_word_range(use_option_sentence_shape_NTM, w1, w2, NULL, NULL))
Config__Inclusions__UseOptions__set_immediate_option_flags(w1, w2, NULL);
}
options_file_w2 = lexer_wordcount - 1;
fclose(FMAN);
}
#line 351 "inform7/Chapter 4/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 377 "inform7/Chapter 4/Debugging Log.w"
int Log__Aspects__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__Aspects__set(int aspect, int state) {
the_debugging_aspects[aspect].on_or_off = state;
}
#line 391 "inform7/Chapter 4/Debugging Log.w"
void 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 421 "inform7/Chapter 4/Debugging Log.w"
int include_in_debugging_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 424 "inform7/Chapter 4/Debugging Log.w"
int debugging_log_request_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 430 "inform7/Chapter 4/Debugging Log.w"
#line 434 "inform7/Chapter 4/Debugging Log.w"
void Log__Aspects__switch_on(int w1, int w2, int new_state) {
LOGIF(DEBUGGING_LOG_INCLUSIONS, "Set contents of debugging log: $W -> %s\n",
w1, w2, new_state?"TRUE":"FALSE");
{
#line 459 "inform7/Chapter 4/Debugging Log.w"
parse_nt_against_word_range(include_in_debugging_sentence_subject_NTM, w1, w2, NULL, NULL);
if (most_recent_result & ONLY_DLR) set_all_aspects(1-new_state);
if (most_recent_result & EVERYTHING_DLR) { set_all_aspects(new_state); return; }
if (most_recent_result & NOTHING_DLR) { set_all_aspects(1-new_state); return; }
if (most_recent_result & SOMETHING_DLR) {
GET_RW(debugging_log_request_NTM, 1, w1, w2);
{
#line 472 "inform7/Chapter 4/Debugging Log.w"
int i;
debugging_aspect *da;
for (i=0; ; i++) {
da = &(the_debugging_aspects[i]);
if (*(da->da_word1) == 0) break;
if (strcmp(Text__word_text(w1), da->da_word1) != 0) continue;
if (w2 > w1) {
if (*(da->da_word2) == 0) continue;
if (strcmp(Text__word_text(w1+1), da->da_word2) != 0) continue;
}
if (w2 > w1+1) {
if (*(da->da_word3) == 0) continue;
if (strcmp(Text__word_text(w1+2), da->da_word3) != 0) continue;
}
if (w2 > w1+2) continue;
da->on_or_off = new_state;
return;
}
}
#line 465 "inform7/Chapter 4/Debugging Log.w"
;
}
if (most_recent_result & PREFORM_DLR) { Text__Languages__watch(most_recent_result_p, new_state); return; }
}
#line 438 "inform7/Chapter 4/Debugging Log.w"
;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C4UnknownDA));
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 509 "inform7/Chapter 4/Debugging Log.w"
void Log__Aspects__set_from_command_line(char *text) {
int i, parity = TRUE, list_mode = FALSE;
debugging_aspect *da;
if (strcmp(text, "everything") == 0) { set_all_aspects(TRUE); return; }
if (strcmp(text, "nothing") == 0) { 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) {
STREAM_WRITE(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;
STREAM_WRITE(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 550 "inform7/Chapter 4/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 569 "inform7/Chapter 4/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) { set_all_aspects(TRUE); return; }
if (strcmp(text, "nothing") == 0) { 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__Aspects__set(i, TRUE); return; }
}
internal_error("unknown *** debugging aspect name");
} else {
verbose_checking_state = (verbose_checking_state)?FALSE:TRUE;
if (verbose_checking_state == FALSE) {
set_all_aspects(FALSE);
} else {
Log__Aspects__set(MATCHING_DA, TRUE);
Log__Aspects__set(KIND_CHECKING_DA, TRUE);
Log__Aspects__set(LOCAL_VARIABLES_DA, TRUE);
}
}
}
#line 606 "inform7/Chapter 4/Debugging Log.w"
void 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 show_debugging_contents(void) {
if (Log__Aspects__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"); show_debugging_settings_with_state(TRUE);
LOG("Omitted:\n"); show_debugging_settings_with_state(FALSE);
}
#line 634 "inform7/Chapter 4/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.");
Formats__HTML__Javascript__paste(ifl, -1, -1, paste_text);
INDEX("&nbsp;%s<br>", paste_text);
}
}
#line 668 "inform7/Chapter 4/Debugging Log.w"
int mlc_backtrace_sp = 0;
meaning_list *mlc_backtrace[MAXIMUM_MLC_BACKTRACE];
char *mlc_backtrace_at[MAXIMUM_MLC_BACKTRACE];
void Log__mlc_backtrace(void) {
int i;
if (mlc_backtrace_sp == 0) return;
LOG("MLC backtrace:\n");
for (i=0; i<mlc_backtrace_sp; i++) {
LOG("%d: %s\n$m", i, mlc_backtrace_at[i], mlc_backtrace[i]);
}
LOG("End of MLC backtrace\n");
}
#line 690 "inform7/Chapter 4/Debugging Log.w"
void 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 718 "inform7/Chapter 4/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); STREAM_WRITE(dl, format_string, ival); break;
case 'g':
dval = va_arg(ap, double); STREAM_WRITE(dl, format_string, dval); break;
case 's':
for (sval = va_arg(ap, char *); *sval; sval++) STREAM_PUT(dl, *sval); break;
case '%': STREAM_PUT(dl, '%'); break;
default:
STREAM_WRITE(dl, "*** Bad escape: <%s> ***\n", format_string);
internal_error("Unknown % string escape in dlprintf");
}
}
#line 698 "inform7/Chapter 4/Debugging Log.w"
; break;
case '$':
{
#line 748 "inform7/Chapter 4/Debugging Log.w"
p++;
switch (*p) {
case 0: STREAM_PUT(dl, '$'); p--; break; /* a literal dollar was last character */
case '$': STREAM_PUT(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 *, Semantics__BPs__log)
SINGLE_ESCAPE('A', action_pattern *, Plugins__Actions__Patterns__log)
SINGLE_ESCAPE('a', adjectival_phrase *, Semantics__Adjectives__log)
SINGLE_ESCAPE('B', table *, Data__Tables__log)
SINGLE_ESCAPE('b', booking *, Code__Rules__Bookings__log)
SINGLE_ESCAPE('C', table_column *, Data__Tables__Columns__log)
DOUBLE_ESCAPE('c', int, int, Text__log_raw)
SINGLE_ESCAPE('D', pcalc_prop *, Calculus__Propositions__log)
SINGLE_ESCAPE('d', extension_dictionary_entry *, Extensions__Dictionary__Entries__log)
SINGLE_ESCAPE('E', invocation_list *, Code__Invocations__Lists__log)
SINGLE_ESCAPE('e', invocation *, Code__Invocations__log)
DOUBLE_ESCAPE('F', int, int, Text__log_with_whitespace)
/* escape |$f| is vacant */
SINGLE_ESCAPE('G', grammar_verb *, Plugins__Parsing__Verbs__log)
SINGLE_ESCAPE('g', grammar_line *, Plugins__Parsing__Lines__log)
SINGLE_ESCAPE('H', heading *, Parser__Sentences__Headings__log)
SINGLE_ESCAPE('h', ph_type_data *, Code__Phrases__TypeData__log)
SINGLE_ESCAPE('I', inference *, World__Inferences__log)
SINGLE_ESCAPE('i', i6_schema *, Code__Schemas__log)
SINGLE_ESCAPE('J', natural_language *, Text__Languages__log)
SINGLE_ESCAPE('j', inference_subject *, World__Subjects__log)
SINGLE_ESCAPE('K', rulebook *, Code__Rulebooks__log)
SINGLE_ESCAPE('k', local_variable *, Code__LocalVariables__log)
SINGLE_ESCAPE('L', action_name_list *, Plugins__Actions__Lists__log)
SINGLE_ESCAPE('l', action_name *, Plugins__Actions__log)
SINGLE_ESCAPE('M', excerpt_meaning *, Semantics__Nouns__ExcerptMeanings__log)
SINGLE_ESCAPE('m', meaning_list *, Parser__SP__MeaningLists__log)
SINGLE_ESCAPE('N', int, Parser__Nodes__Types__log)
SINGLE_ESCAPE('n', int, World__Inferences__log_kind)
SINGLE_ESCAPE('O', instance *, Data__Instances__log)
SINGLE_ESCAPE('o', pcalc_prop *, Calculus__Atoms__log)
SINGLE_ESCAPE('P', parse_node *, Parser__Nodes__log)
SINGLE_ESCAPE('p', unsigned int, Parser__SP__MeaningLists__log_production)
SINGLE_ESCAPE('Q', unit_sequence *, Kinds__Dimensions__log_unit_sequence)
SINGLE_ESCAPE('q', equation *, Data__Equations__log)
SINGLE_ESCAPE('R', phrase *, Code__Phrases__log)
SINGLE_ESCAPE('r', adjective_list_entry *, Specifications__Conditions__log_adjective_list_entry)
SINGLE_ESCAPE('S', specification *, Specifications__log_concisely)
SINGLE_ESCAPE('s', int, Specifications__Taxa__log)
SINGLE_ESCAPE('T', parse_node *, Parser__Nodes__log_subtree_at_current_margin)
SINGLE_ESCAPE('t', time_period *, Code__Chronology__TimePeriods__log)
SINGLE_ESCAPE('U', ph_usage_data *, Code__Phrases__Usage__log)
SINGLE_ESCAPE('u', kind *, Kinds__log)
SINGLE_ESCAPE('V', int, Parser__Sentences__VPs__log)
SINGLE_ESCAPE('v', vocabulary_entry *, Text__Vocabulary__log)
DOUBLE_ESCAPE('W', int, int, Text__log)
SINGLE_ESCAPE('w', word_assemblage *, Text__Words__log)
SINGLE_ESCAPE('X', specification *, Specifications__log_exhaustively)
SINGLE_ESCAPE('x', extension_file *, Extensions__Files__log)
SINGLE_ESCAPE('Y', property *, Properties__log)
DOUBLE_ESCAPE('y', int, int, Text__log_spaceless)
SINGLE_ESCAPE('Z', nonlocal_variable *, Data__NonlocalVariables__log)
SINGLE_ESCAPE('z', nametag *, Data__Nametags__log)
default:
STREAM_WRITE(dl, "*** Bad escape: '$%c' ***\n", *p);
internal_error("Unknown % string escape in dlprintf");
}
}
#line 699 "inform7/Chapter 4/Debugging Log.w"
; break;
case '"': if (logging_to_I6_text) STREAM_PUT(dl, '~'); else STREAM_PUT(dl, '"'); break;
case '\n': if (logging_to_I6_text) STREAM_PUT(dl, '^'); else STREAM_PUT(dl, '\n'); break;
default: STREAM_PUT(dl, *p); break;
}
va_end(ap); /* macro to end variable argument processing */
}
#line 239 "inform7/Chapter 5/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 Text__start(void) {
lexer_wordcount = 0;
Text__ensure_space_up_to(50000); /* the Standard Rules are about 44,000 words */
allocate_lexer_workspace_chunk();
Text__Vocabulary__start_hash_table();
}
#line 258 "inform7/Chapter 5/Lexer.w"
int current_lw_array_size = 0, next_lw_array_size = 75000;
void Text__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 296 "inform7/Chapter 5/Lexer.w"
void 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;
allocate_lexer_workspace_chunk();
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 allocate_lexer_workspace_chunk(void) {
lexer_workspace = ((char *) (Memory__I7_malloc(TEXT_STORAGE_CHUNK_SIZE, LEXER_TEXT_MREASON)));
lexer_workspace_allocated += TEXT_STORAGE_CHUNK_SIZE;
lexer_hwm = lexer_workspace;
lexer_workspace_end = lexer_workspace + TEXT_STORAGE_CHUNK_SIZE;
}
#line 325 "inform7/Chapter 5/Lexer.w"
char *Text__copy_to_memory(char *p) {
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 364 "inform7/Chapter 5/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 374 "inform7/Chapter 5/Lexer.w"
int Text__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 391 "inform7/Chapter 5/Lexer.w"
int Text__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 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 406 "inform7/Chapter 5/Lexer.w"
vocabulary_entry *Text__word(int wn) {
return lw_array[wn].lw_identity;
}
void Text__set_word(int wn, vocabulary_entry *ve) {
lw_array[wn].lw_identity = ve;
}
int Text__break_before(int wn) {
return lw_array[wn].lw_break;
}
source_file *Text__file_of_origin(int wn) {
return lw_array[wn].lw_source.file_of_origin;
}
source_location Text__word_location(int wn) {
return lw_array[wn].lw_source;
}
char *Text__word_raw_text(int wn) {
return lw_array[wn].lw_rawtext;
}
void Text__set_word_raw_text(int wn, char *rt) {
lw_array[wn].lw_rawtext = rt;
}
char *Text__word_text(int wn) {
return lw_array[wn].lw_text;
}
void Text__set_word_text(int wn, char *rt) {
lw_array[wn].lw_text = rt;
}
void Text__word_copy(int to, int from) {
lw_array[to] = lw_array[from];
}
#line 467 "inform7/Chapter 5/Lexer.w"
int lxs_previous_char_in_raw_feed; /* Preceding character in raw file read */
#line 480 "inform7/Chapter 5/Lexer.w"
int lxs_kind_of_word; /* One of the defined values above */
#line 492 "inform7/Chapter 5/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 511 "inform7/Chapter 5/Lexer.w"
void 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 550 "inform7/Chapter 5/Lexer.w"
int lexer_feed_started_at = -1;
void Text__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;
reset_lexer();
LOGIF(LEXICAL_OUTPUT, "Lexer feed began at %d\n", lexer_feed_started_at);
}
void Text__feed_ends(int *range_read_w1, int *range_read_w2, int extra_padding,
char *problem_source_description) {
if (lexer_feed_started_at == -1) internal_error("lexer feeder ended without starting");
{
#line 589 "inform7/Chapter 5/Lexer.w"
if (extra_padding == FALSE) {
feed_char_into_lexer(' ');
} else {
feed_char_into_lexer(' ');
feed_char_into_lexer('\n');
feed_char_into_lexer('\n');
feed_char_into_lexer('\n');
feed_char_into_lexer('\n');
feed_char_into_lexer(' ');
}
}
#line 564 "inform7/Chapter 5/Lexer.w"
;
*range_read_w1 = lexer_feed_started_at; *range_read_w2 = lexer_wordcount-1;
lexer_feed_started_at = -1;
LOGIF(LEXICAL_OUTPUT, "Lexer feed ended at %d\n", *range_read_w2);
{
#line 605 "inform7/Chapter 5/Lexer.w"
if (lxs_kind_of_word != ORDINARY_KW) {
if (lexer_wordcount >= 20) {
LOG("Last words: $W\n", lexer_wordcount-20, lexer_wordcount-1);
} else if (lexer_wordcount >= 1) {
LOG("Last words: $W\n", 0, lexer_wordcount-1);
} else {
LOG("No words recorded\n");
}
}
if (lxs_kind_of_word == STRING_KW) {
Problems__lexical_problem(_P_(C5UnendingQuote),
"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__lexical_problem(_P_(C5UnendingComment),
"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__lexical_problem(_P_(C5UnendingI6),
"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 569 "inform7/Chapter 5/Lexer.w"
;
}
#line 674 "inform7/Chapter 5/Lexer.w"
void Text__feed_triplet(int last_cr, int cr, int next_cr) {
lxs_previous_char_in_raw_feed = last_cr;
int space = FALSE;
if (Text__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) {
feed_char_into_lexer(' ');
feed_char_into_lexer((char) cr); /* which might take us into literal mode, so to be careful... */
if (lxs_literal_mode == FALSE) feed_char_into_lexer(' ');
} else feed_char_into_lexer((char) cr);
if ((cr == '\n') && (lexer_position.file_of_origin))
lexer_position.line_number++;
}
#line 731 "inform7/Chapter 5/Lexer.w"
void feed_char_into_lexer(char c) {
ensure_lexer_hwm_can_be_raised_by(MAX_WORD_LENGTH, TRUE);
if (lxs_literal_mode) {
{
#line 1010 "inform7/Chapter 5/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 735 "inform7/Chapter 5/Lexer.w"
;
if (lxs_kind_of_word == STRING_KW) {
{
#line 1057 "inform7/Chapter 5/Lexer.w"
if ((lexer_divide_strings_at_text_substitutions) && (c == TEXT_SUBSTITUTION_BEGIN)) {
feed_char_into_lexer(STRING_END); /* feed |"| to close the old string */
feed_char_into_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 737 "inform7/Chapter 5/Lexer.w"
;
{
#line 827 "inform7/Chapter 5/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 738 "inform7/Chapter 5/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 776 "inform7/Chapter 5/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 744 "inform7/Chapter 5/Lexer.w"
;
if (lexer_word != lexer_hwm)
{
#line 852 "inform7/Chapter 5/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 872 "inform7/Chapter 5/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__lexical_problem(_P_(C5TooMuchQuotedText),
"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__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__lexical_problem(_P_(C5WordTooLong),
"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 858 "inform7/Chapter 5/Lexer.w"
;
{
#line 929 "inform7/Chapter 5/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;
}
Text__Vocabulary__identify_word(lexer_wordcount); /* which sets |lw_array[lexer_wordcount].lw_identity| */
lexer_wordcount++;
Text__ensure_space_up_to(lexer_wordcount);
}
#line 859 "inform7/Chapter 5/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 745 "inform7/Chapter 5/Lexer.w"
;
if (c == '\n')
{
#line 808 "inform7/Chapter 5/Lexer.w"
if (lxs_this_line_is_empty_so_far) {
int i;
for (i=0; PARAGRAPH_BREAK[i]; i++)
feed_char_into_lexer(PARAGRAPH_BREAK[i]);
feed_char_into_lexer(' ');
}
lxs_this_line_is_empty_so_far = TRUE;
}
#line 746 "inform7/Chapter 5/Lexer.w"
;
return;
}
/* otherwise record the current character as part of the word being built */
*(lexer_hwm++) = c;
if (lxs_scanning_text_substitution) {
{
#line 1084 "inform7/Chapter 5/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 |,| */
feed_char_into_lexer(' '); /* then feed a space to end the |,| word */
feed_char_into_lexer(STRING_BEGIN); /* then feed |"| to open a new string */
}
}
#line 754 "inform7/Chapter 5/Lexer.w"
;
}
if (lxs_this_word_is_empty_so_far) {
{
#line 793 "inform7/Chapter 5/Lexer.w"
if ((lxs_most_significant_space_char == '\n') && (lxs_number_of_tab_stops >= 1))
lw_array[lexer_wordcount].lw_break =
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 758 "inform7/Chapter 5/Lexer.w"
;
{
#line 968 "inform7/Chapter 5/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 = "(-";
Text__Vocabulary__identify_word(lexer_wordcount-1); /* and re-identify */
}
lexer_hwm--; /* erase the just-recorded |INFORM6_ESCAPE_BEGIN_2| character */
break;
}
}
#line 759 "inform7/Chapter 5/Lexer.w"
;
}
lxs_this_word_is_empty_so_far = FALSE;
lxs_this_line_is_empty_so_far = FALSE;
}
#line 60 "inform7/Chapter 5/Read Source Text.w"
int Text__Reader__read_extension_source_text(extension_file *EF, char *filename,
char *synopsis, int documentation_only) {
int rv = read_file(NULL, filename, synopsis, EF, documentation_only);
if (Log__Aspects__on(LEXICAL_OUTPUT_DA)) Text__log_lexer_output();
return rv;
}
void Text__Reader__read_primary_source_text(void) {
Text__feed_into_lexer(MANDATORY_INSERTED_TEXT, FALSE, NULL);
Log__read_further_mandatory_text();
if (bundle_name != NULL)
read_file(bundle_name, Files__Filenames__source_filename_relative_to_bundle("story.ni"),
"your source text", NULL, FALSE);
else read_file(NULL, source_text_file, "the source text", NULL, FALSE);
}
#line 89 "inform7/Chapter 5/Read Source Text.w"
int read_file(char *pathname, char *leafname, 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->words_of_quoted_text = 0;
sf->extension_provided = EF;
strcpy(sf->leafname, leafname);
int origin_tried = ORIGIN_WAS_PRIMARY_SOURCE;
{
#line 123 "inform7/Chapter 5/Read Source Text.w"
sf->handle = NULL;
if (EF) {
int i;
for (i=1; i<=3; i++)
if (sf->handle == NULL) {
switch (i) {
case 1:
origin_tried = ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA;
pathname = pathname_of_materials_extensions;
break;
case 2:
origin_tried = ORIGIN_WAS_USER_EXTENSIONS_AREA;
pathname = pathname_of_extensions;
break;
case 3:
origin_tried = ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA;
pathname = pathname_of_built_in_extensions;
break;
}
sprintf(sf->filename, "%s%c%s", pathname, FOLDER_SEPARATOR, leafname);
sf->handle = Platform__iso_fopen_caseless(sf->filename, "r");
if (sf->handle == NULL) {
char extended_name[MAX_FILENAME_LENGTH];
sprintf(extended_name, "%s.i7x", sf->filename);
sf->handle = Platform__iso_fopen_caseless(extended_name, "r");
if (sf->handle) strcpy(sf->filename, extended_name);
}
}
if (sf->handle == NULL) {
LOG("Extension failed: '%s'\n", leafname);
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, synopsis);
Problems__handmade_problem(_P_(C5BogusExtension));
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.");
Problems__issue_problem_end();
return -1;
}
} else {
if (pathname == NULL) strcpy(sf->filename, leafname);
else sprintf(sf->filename, "%s%c%s", pathname, FOLDER_SEPARATOR, leafname);
sf->handle = Platform__iso_fopen(sf->filename, "r");
if (sf->handle == NULL)
Problems__Fatal__issue2("Error: can't open source text file", sf->filename);
}
}
#line 100 "inform7/Chapter 5/Read Source Text.w"
;
if (EF) Extensions__Files__set_corresponding_source_file(EF, sf);
feed_file_into_lexer(sf, leafname, documentation_only);
fclose(sf->handle);
if (documentation_only == FALSE)
{
#line 183 "inform7/Chapter 5/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 = Text__Reader__sf_total_word_count(sf);
STREAM_WRITE(STDOUT, message, synopsis, wc);
STREAM_FLUSH(STDOUT);
LOG(message, synopsis, wc);
}
#line 107 "inform7/Chapter 5/Read Source Text.w"
;
return origin_tried;
}
#line 205 "inform7/Chapter 5/Read Source Text.w"
void feed_file_into_lexer(source_file *sf, char *leafname, int documentation_only) {
source_location top_of_file;
int words_fed_w1, words_fed_w2;
int cr, last_cr, next_cr, read_cr, newline_char = 0;
top_of_file.file_of_origin = sf;
top_of_file.line_number = 1;
Text__feed_begins(top_of_file);
if (documentation_only) lexer_wait_for_dashes = TRUE;
last_cr = ' '; cr = ' '; next_cr = Text__Reader__utf8_fgetc(sf->handle, NULL, TRUE);
if (next_cr == 0xFEFF) next_cr = Text__Reader__utf8_fgetc(sf->handle, NULL, TRUE); /* Unicode BOM code */
if (next_cr != EOF)
while (((read_cr = Text__Reader__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;
}
Text__feed_triplet(last_cr, cr, next_cr);
}
if (primary_source_file == sf) leafname = "main source text";
Text__feed_ends(&words_fed_w1, &words_fed_w2, TRUE, leafname);
{
#line 251 "inform7/Chapter 5/Read Source Text.w"
int wc;
for (wc=words_fed_w1; wc<=words_fed_w2; wc++)
sf->words_of_source += Text__Reader__word_count(wc);
}
#line 244 "inform7/Chapter 5/Read Source Text.w"
;
}
#line 258 "inform7/Chapter 5/Read Source Text.w"
int Text__Reader__word_count(int wc) {
int N = 0;
char *p = Text__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 (Text__word(wc) != PARBREAK_V)
for (; *p != 0; p++)
if ((Text__is_punctuation(*p) == FALSE) && (*p != '|')) {
N++;
break;
}
}
return N;
}
#line 287 "inform7/Chapter 5/Read Source Text.w"
int Text__Reader__sf_total_word_count(source_file *sf) {
return sf->words_of_source + sf->words_of_quoted_text;
}
#line 297 "inform7/Chapter 5/Read Source Text.w"
char *Text__Reader__sf_get_filename(source_file *sf) {
if (sf == NULL) internal_error("tried to read filename of null source file");
return sf->filename;
}
extension_file *Text__Reader__sf_get_extension_corresponding(source_file *sf) {
if (sf == NULL) return NULL;
return sf->extension_provided;
}
source_file *Text__Reader__filename_to_source_file(char *filename) {
source_file *sf;
LOOP_OVER(sf, source_file) {
if (strcmp(sf->filename, filename) == 0) return sf;
if (strcmp(sf->leafname, filename) == 0) return sf;
}
return NULL;
}
#line 340 "inform7/Chapter 5/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 Text__Reader__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 373 "inform7/Chapter 5/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 353 "inform7/Chapter 5/Read Source Text.w"
;
{
#line 401 "inform7/Chapter 5/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 354 "inform7/Chapter 5/Read Source Text.w"
;
{
#line 416 "inform7/Chapter 5/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 355 "inform7/Chapter 5/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 441 "inform7/Chapter 5/Read Source Text.w"
int lexer_feed_w1, lexer_feed_w2; /* word range made in last call to |Text__feed_into_lexer| */
void Text__feed_into_lexer(char *text, int expand_strings, char *nonstandard) {
int i;
source_location as_if_from_nowhere;
as_if_from_nowhere.file_of_origin = NULL;
as_if_from_nowhere.line_number = 1;
Text__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 (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;
Text__feed_triplet(last_cr, cr, next_cr);
}
Text__feed_ends(&lexer_feed_w1, &lexer_feed_w2, FALSE, NULL);
Text__Vocabulary__identify_word_range(lexer_feed_w1, lexer_feed_w2);
}
#line 484 "inform7/Chapter 5/Read Source Text.w"
int Text__splice_words(int w1, int w2) {
int i;
Text__ensure_space_up_to(lexer_wordcount + w2 - w1 + 1);
for (i=0; i<=w2-w1; i++)
Text__word_copy(lexer_wordcount+i, w1+i);
i = lexer_wordcount;
lexer_wordcount += w2-w1+1;
return i;
}
#line 499 "inform7/Chapter 5/Read Source Text.w"
int lower_case_splice_words(int w1, int w2) {
int i;
Text__ensure_space_up_to(lexer_wordcount + w2 - w1 + 1);
for (i=0; i<=w2-w1; i++) {
Text__word_copy(lexer_wordcount+i, w1+i);
Text__set_word_raw_text(lexer_wordcount+i, Text__word_text(w1+i));
}
i = lexer_wordcount;
lexer_wordcount += w2-w1+1;
return i;
}
#line 79 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__identify_word(int wn) {
vocabulary_entry *ve = Text__Vocabulary__entry_for_text(Text__word_text(wn));
ve->raw_exemplar = Text__word_raw_text(wn);
Text__set_word(wn, ve);
}
void Text__Vocabulary__identify_word_range(int w1, int w2) {
int i;
for (i=w1; i<=w2; i++) Text__Vocabulary__identify_word(i);
}
#line 94 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__change_text_of_word(int wn, char *new) {
Text__set_word_text(wn, new);
Text__set_word_raw_text(wn, new);
Text__Vocabulary__identify_word(wn);
}
#line 104 "inform7/Chapter 5/Vocabulary.w"
vocabulary_entry *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 (Parser__SP__parse_kind_variable_text(ve)) ve->flags |= KIND_FAST_MC;
if (flags & NUMBER_MC) Text__Languages__mark_as_cardinal(ve);
if (flags & ORDINAL_MC) Text__Languages__mark_as_ordinal(ve);
ve->literal_number_value = val;
ve->one_word_kind = NULL;
return ve;
}
void Text__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 157 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__set_raw_exemplar_to_text(int wn) {
Text__word(wn)->raw_exemplar = Text__word_text(wn);
}
#line 165 "inform7/Chapter 5/Vocabulary.w"
char *Text__Vocabulary__get_exemplar(vocabulary_entry *ve, int raw) {
if (raw) return ve->raw_exemplar;
else return ve->exemplar;
}
#line 174 "inform7/Chapter 5/Vocabulary.w"
int Text__Vocabulary__get_literal_number_value(vocabulary_entry *ve) {
return ve->literal_number_value;
}
void Text__Vocabulary__set_literal_number_value(vocabulary_entry *ve, int val) {
ve->literal_number_value = val;
}
#line 184 "inform7/Chapter 5/Vocabulary.w"
kind *Text__Vocabulary__get_kind(vocabulary_entry *ve) {
return ve->one_word_kind;
}
void Text__Vocabulary__set_kind(vocabulary_entry *ve, kind *K) {
ve->one_word_kind = K;
Text__Vocabulary__set_flags(ve, KIND_FAST_MC);
Text__Languages__mark_vocabulary(ve, k_kind_NTM);
}
#line 201 "inform7/Chapter 5/Vocabulary.w"
int Text__Vocabulary__used_case_sensitively(vocabulary_entry *ve) {
if ((ve->upper_case_form) || (ve->lower_case_form)) return TRUE;
return FALSE;
}
vocabulary_entry *Text__Vocabulary__get_lower_case_form(vocabulary_entry *ve) {
return ve->lower_case_form;
}
vocabulary_entry *Text__Vocabulary__make_case_sensitive(vocabulary_entry *ve) {
if (ve->upper_case_form) return ve->upper_case_form;
ve->upper_case_form =
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 220 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__set_flags(vocabulary_entry *ve, unsigned int t) {
ve->flags |= t;
}
unsigned int Text__Vocabulary__test_vflags(vocabulary_entry *ve, unsigned int t) {
return (ve->flags) & t;
}
unsigned int Text__Vocabulary__test_flags(int wn, unsigned int t) {
return (Text__word(wn)->flags) & t;
}
#line 236 "inform7/Chapter 5/Vocabulary.w"
unsigned int Text__Vocabulary__disjunction_of_flags(int w1, int w2) {
int i;
unsigned int d = 0;
for (i=w1; i<=w2; i++) d |= (Text__word(i)->flags);
return d;
}
#line 246 "inform7/Chapter 5/Vocabulary.w"
void Text__Vocabulary__set_ntb(vocabulary_entry *ve, int R) {
ve->nt_incidence = R;
}
int Text__Vocabulary__get_ntb(vocabulary_entry *ve) {
return ve->nt_incidence;
}
#line 298 "inform7/Chapter 5/Vocabulary.w"
int 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 328 "inform7/Chapter 5/Vocabulary.w"
vocabulary_entry *list_of_vocab_with_hash[HASH_TAB_SIZE];
void Text__Vocabulary__start_hash_table(void) {
int i;
for (i=0; i<HASH_TAB_SIZE; i++) list_of_vocab_with_hash[i] = NULL;
}
#line 343 "inform7/Chapter 5/Vocabulary.w"
int no_vocabulary_entries = 0;
vocabulary_entry *Text__Vocabulary__entry_for_text(char *text) {
vocabulary_entry *new_entry;
int hash_code = 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 = 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 388 "inform7/Chapter 5/Vocabulary.w"
new_entry = 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 365 "inform7/Chapter 5/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 398 "inform7/Chapter 5/Vocabulary.w"
new_entry = 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 376 "inform7/Chapter 5/Vocabulary.w"
;
}
}
#line 409 "inform7/Chapter 5/Vocabulary.w"
vocabulary_entry *Text__Vocabulary__entry_for_partial_text(char *str, int from, int to) {
TEMPORARY_STREAM;
int i;
for (i=from; i<=to; i++) STREAM_PUT(TEMP, str[i]);
STREAM_PUT(TEMP, 0);
int w1 = lexer_wordcount;
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
int w2 = lexer_wordcount-1;
CLOSE_TEMPORARY_STREAM;
if (w2 < w1) return NULL;
return Text__word(w1);
}
#line 429 "inform7/Chapter 5/Vocabulary.w"
int an_ordinal_number(char *fw) {
int i;
for (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 32 "inform7/Chapter 5/Lexical Services.w"
int Text__compare_word_by_strcmp(int w, char *t) {
return (strcmp(Text__word_text(w), t) == 0);
}
int Text__compare_raw_word_by_strcmp(int w, char *t) {
return (strcmp(Text__word_raw_text(w), t) == 0);
}
#line 47 "inform7/Chapter 5/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(*(Text__word_raw_text(wn)))) {
if (Text__text_ending_sentence(wn-1)) return FALSE;
return TRUE;
}
return FALSE;
}
#line 62 "inform7/Chapter 5/Lexical Services.w"
int Text__singly_quoted(int wn) {
if (wn<1) return FALSE;
char *p = Text__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 75 "inform7/Chapter 5/Lexical Services.w"
int Text__text_ending_sentence(int wn) {
char *p = Text__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 95 "inform7/Chapter 5/Lexical Services.w"
int if_start_of_paragraph_NTMR(int w1, int w2, int *X, void **XP) {
#line 96 "inform7/Chapter 5/Lexical Services.w"
if ((w1 == 0) || (compare_word(w1-1, PARBREAK_V))) return TRUE;
return FALSE;
}
#line 111 "inform7/Chapter 5/Lexical Services.w"
int if_start_of_source_text_NTMR(int w1, int w2, int *X, void **XP) {
#line 112 "inform7/Chapter 5/Lexical Services.w"
if ((no_sentences_read == 2) &&
((w1 == 0) || (compare_word(w1-1, PARBREAK_V)))) return TRUE;
return FALSE;
}
#line 120 "inform7/Chapter 5/Lexical Services.w"
int if_not_deliberately_capitalised_NTMR(int w1, int w2, int *X, void **XP) {
#line 121 "inform7/Chapter 5/Lexical Services.w"
if (Text__unexpectedly_upper_case(w1) == FALSE) return TRUE;
return FALSE;
}
#line 130 "inform7/Chapter 5/Lexical Services.w"
void Text__dequote_word(int wn) {
char *previous_text = Text__word_text(wn);
char *dequoted_text;
if (previous_text[0] != '"') return;
Text__set_word_raw_text(wn, Text__copy_to_memory(Text__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;
Text__set_word_text(wn, dequoted_text);
LOGIF(VOCABULARY, "Dequoting word %d <%s> to <%s>\n",
wn, previous_text, dequoted_text);
Text__Vocabulary__identify_word(wn);
Text__Vocabulary__set_raw_exemplar_to_text(wn);
}
#line 160 "inform7/Chapter 5/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 192 "inform7/Chapter 5/Lexical Services.w"
int Text__compare_word_range(int w1, int w2, int w3, int w4) {
int j;
if (w4-w3 != w2-w1) return FALSE;
if ((w1<0) || (w3<0)) return FALSE;
for (j=0; j<=w2-w1; j++)
if (compare_words(w1+j, w3+j) == FALSE) return FALSE;
return TRUE;
}
#line 204 "inform7/Chapter 5/Lexical Services.w"
int Text__compare_perhaps_quoted_word_range(int w1, int w2, int w3, int w4) {
int j;
if (w4-w3 != w2-w1) return FALSE;
if ((w1<0) || (w3<0)) return FALSE;
for (j=0; j<=w2-w1; j++) {
if (compare_words(w1+j, w3+j) == FALSE) {
if ((Text__Vocabulary__test_flags(w1+j, (TEXT_MC+TEXTWITHSUBS_MC))) &&
(Text__Vocabulary__test_flags(w3+j, (TEXT_MC+TEXTWITHSUBS_MC))) &&
(strcmp(Text__word_raw_text(w1+j), Text__word_raw_text(w3+j)) == 0))
continue;
return FALSE;
}
}
return TRUE;
}
#line 224 "inform7/Chapter 5/Lexical Services.w"
int Text__rangecmp(int x1, int x2, int y1, int y2) {
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(Text__word_text(x1 + n), Text__word_text(y1 + n));
if (delta != 0) return delta;
}
return l1 - l2;
}
#line 241 "inform7/Chapter 5/Lexical Services.w"
int Text__paired_brackets(int w1, int w2) {
if ((Text__word(w1) == OPENBRACKET_V) &&
(Text__word(w2) == CLOSEBRACKET_V) &&
(Text__mismatched_brackets(w1+1, w2-1) == FALSE))
return TRUE;
return FALSE;
}
#line 252 "inform7/Chapter 5/Lexical Services.w"
int Text__mismatched_brackets(int w1, int w2) {
int i, bl = 0;
for (i=w1; i<=w2; i++) {
if ((Text__word(i) == OPENBRACKET_V) || (Text__word(i) == OPENBRACE_V)) bl++;
if ((Text__word(i) == CLOSEBRACKET_V) || (Text__word(i) == CLOSEBRACE_V)) bl--;
if (bl < 0) return TRUE;
}
if (bl != 0) return TRUE;
return FALSE;
}
#line 267 "inform7/Chapter 5/Lexical Services.w"
int balanced_text_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 269 "inform7/Chapter 5/Lexical Services.w"
#line 281 "inform7/Chapter 5/Lexical Services.w"
int Text__last_word_of_formatted_text(int w1, int w2, int tab_flag) {
int i;
if (w2 == w1) return w1;
for (i=w1+1; i<=w2; i++)
if (((tab_flag) && (Text__break_before(i) == '\t')) ||
(Text__indentation_level(i) > 0) ||
(Text__break_before(i) == '\n'))
return i-1;
return w2;
}
#line 301 "inform7/Chapter 5/Lexical Services.w"
int list_comma_division_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 303 "inform7/Chapter 5/Lexical Services.w"
#line 309 "inform7/Chapter 5/Lexical Services.w"
void Text__print_literal_string_to_file(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 319 "inform7/Chapter 5/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 341 "inform7/Chapter 5/Lexical Services.w"
void Text__print_text_to_stream(int w1, int w2, OUTPUT_STREAM) {
if ((w1 < 0) || (w1 > w2)) return;
int j;
for (j=w1; j<=w2; j++) {
Text__print_literal_string_to_file(OUT, Text__word_text(j));
if (j<w2) WRITE(" ");
}
}
void Text__print_text_to_string(int w1, int w2, char *str) {
str[0] = 0;
if ((w1 < 0) || (w1 > w2)) return;
int j;
for (j=w1; j<=w2; j++) {
sprintf(str+Platform__strlen(str), "%s", Text__word_text(j));
if (j<w2) sprintf(str+Platform__strlen(str), " ");
}
}
void Text__print_text_to_string_truncated(int w1, int w2, char *str, int max) {
str[0] = 0;
if ((w1 < 0) || (w1 > w2)) return;
int j;
for (j=w1; j<=w2; j++) {
char *p = Text__word_text(j);
char *p2 = "";
int sp = FALSE;
if (j<w2) { sp = TRUE; p2 = Text__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 387 "inform7/Chapter 5/Lexical Services.w"
void Text__print_modest_sized_text_to_string(int w1, int w2, char *str) {
int i, j, l; char *p = NULL;
if (w1 < 0) {
sprintf(str+Platform__strlen(str), "<no text>"); return;
}
str[0] = 0;
for (i=w1; i<=w2; i++) {
int space = TRUE;
if (i == w1) 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;
}
p = Text__word_raw_text(i);
if (space) sprintf(str+Platform__strlen(str), " ");
l = Platform__strlen(p);
if (l > STRING_TOLERANCE_LIMIT+5) {
for (j=0; j<STRING_TOLERANCE_LIMIT/2; j++)
sprintf(str+Platform__strlen(str), "%c", p[j]);
sprintf(str+Platform__strlen(str), " [...] ");
for (j=STRING_TOLERANCE_LIMIT/2; j>0; j--)
sprintf(str+Platform__strlen(str), "%c", p[l-j]);
} else {
sprintf(str+Platform__strlen(str), "%s", p);
}
if ((i >= w1+1) && (compare_word(i-1, OPENI6_V))) {
sprintf(str+Platform__strlen(str), "-)");
}
}
}
#line 442 "inform7/Chapter 5/Lexical Services.w"
void Text__print_raw_text_to_stream(int w1, int w2, OUTPUT_STREAM) {
int j;
if ((w1 < 0) || (w1>w2)) { WRITE("?%d,%d?", w1, w2); return; }
for (j=w1; j<=w2; j++) {
char *p = Text__word_raw_text(j);
char *p2 = "";
int sp = FALSE;
if (j<w2) { sp = TRUE; p2 = Text__word_raw_text(j+1); }
Text__print_literal_string_to_file(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(" ");
}
}
void Text__print_raw_text_to_string(int w1, int w2, char *str) {
int j;
str[0] = 0;
for (j=w1; j<=w2; j++) {
char *p = Text__word_raw_text(j);
char *p2 = "";
int sp = FALSE;
if (j<w2) { sp = TRUE; p2 = Text__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 Text__print_raw_text_to_string_truncated(int w1, int w2, char *str, int max) {
int j;
str[0] = 0;
for (j=w1; j<=w2; j++) {
char *p = Text__word_raw_text(j);
char *p2 = "";
int sp = FALSE;
if (j<w2) { sp = TRUE; p2 = Text__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 501 "inform7/Chapter 5/Lexical Services.w"
void Text__print_raw_text_within_i6_literal(OUTPUT_STREAM, int w1, int w2) {
int j, k;
for (j=w1; j<=w2; j++) {
char *str = Text__word_raw_text(j);
if (j>w1) WRITE(" ");
for (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 522 "inform7/Chapter 5/Lexical Services.w"
void Text__log(int w1, int w2) {
if ((w1 >= 0) && (w1 <= w2))
Text__print_text_to_stream(w1, w2, dl);
}
void Text__log_raw(int w1, int w2) {
if ((w1 >= 0) && (w1 <= w2))
Text__print_raw_text_to_stream(w1, w2, dl);
}
#line 536 "inform7/Chapter 5/Lexical Services.w"
void Text__log_with_whitespace(int w1, int w2) {
int i;
if (w1<0) return;
for (i=w1; i<=w2; i++) {
char *del = "[sp]";
if (Text__break_before(i) == '\n') del = "[cr]";
if (Text__break_before(i) == '\t') del = "[tab]";
if (Text__indentation_level(i) > 0) del = "[cr+tab(s)]";
LOG("%s%s", Text__word_text(i), del);
if (i<w2) LOG(" ");
}
LOG("\n");
}
#line 555 "inform7/Chapter 5/Lexical Services.w"
void Text__log_spaceless(int w1, int w2) {
int i;
if (w1<0) return;
for (i=w1; i<=w2; i++) {
char *p = Text__word_text(i);
int j;
for (j=0; p[j]; j++) {
if ((p[j] >= 0) || (p[j] <= 31)) LOG(" ");
else LOG("%c", p[j]);
}
if (i<w2) LOG(" ");
}
}
#line 572 "inform7/Chapter 5/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, Text__word_raw_text(i), Text__word_text(i), Text__break_before(i));
}
LOG("------\n");
}
#line 69 "inform7/Chapter 5/Tries and Inflections.w"
match_trie *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 5/Tries and Inflections.w"
match_avinue *Text__Inflections__new_avinue(int from_start) {
match_avinue *A = CREATE(match_avinue);
A->next = NULL;
A->the_trie = new_trie_node(from_start);
return A;
}
match_avinue *Text__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 5/Tries and Inflections.w"
char *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 5/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 5/Tries and Inflections.w"
;
match_trie *prev = NULL, *pos = T;
{
#line 277 "inform7/Chapter 5/Tries and Inflections.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 139 "inform7/Chapter 5/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 */
char c = (i<0)?0:(p[i]); /* i.e., zero at the two ends of the text */
if ((c >= 0x20) && (c <= 0x7f)) c = Platform__tolower(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 5/Tries and Inflections.w"
int ambig = 0, unambig = 0;
match_trie *point;
for (point = pos; point; point = point->next)
if (trie_node_ambiguous(point)) ambig++;
else unambig++;
FauxWhileLoop:
if (pos) {
if ((add_outcome == NULL) || (trie_node_ambiguous(pos) == FALSE))
if (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 5/Tries and Inflections.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 229 "inform7/Chapter 5/Tries and Inflections.w"
;
continue;
}
pos = pos->next;
goto FauxWhileLoop;
}
}
#line 172 "inform7/Chapter 5/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 5/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 = new_trie_node(nt);
strcpy(new_pos->group_characters, from);
} else if (c == '*') new_pos = new_trie_node(TRIE_ANYTHING);
else new_pos = 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 5/Tries and Inflections.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 272 "inform7/Chapter 5/Tries and Inflections.w"
; continue;
}
#line 183 "inform7/Chapter 5/Tries and Inflections.w"
;
}
if ((pos) && (pos->match_character == TRIE_ANYTHING))
{
#line 277 "inform7/Chapter 5/Tries and Inflections.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 185 "inform7/Chapter 5/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 5/Tries and Inflections.w"
prev->on_success = new_trie_node(TRIE_STOP);
prev->on_success->match_outcome = add_outcome;
return add_outcome;
}
#line 190 "inform7/Chapter 5/Tries and Inflections.w"
else
{
#line 292 "inform7/Chapter 5/Tries and Inflections.w"
prev->on_success = new_trie_node(TRIE_STOP);
prev->on_success->match_outcome = add_outcome;
return add_outcome;
}
#line 192 "inform7/Chapter 5/Tries and Inflections.w"
;
}
#line 300 "inform7/Chapter 5/Tries and Inflections.w"
int 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 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 5/Tries and Inflections.w"
char *search_avinue(match_avinue *T, char *p) {
char *result = NULL;
while ((T) && (result == NULL)) {
result = search_trie(T->the_trie, p, NULL);
T = T->next;
}
return result;
}
#line 343 "inform7/Chapter 5/Tries and Inflections.w"
void Text__Inflections__log_avinue(match_avinue *A) {
LOG("Avinue:\n"); LOG_INDENT;
int n = 1;
while (A) {
LOG("Trie %d:\n", n++); LOG_INDENT;
log_trie_recursively(A->the_trie);
LOG_OUTDENT;
A = A->next;
}
LOG_OUTDENT;
}
void 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; log_trie_recursively(T->on_success); LOG_OUTDENT;
}
}
}
#line 383 "inform7/Chapter 5/Tries and Inflections.w"
int suffix_inflection(match_avinue *T, char *to, char *from, int max_length) {
int success = TRUE;
char *result = 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 5/Tries and Inflections.w"
word_assemblage Text__Inflections__apply_trie_to_wa(word_assemblage wa, match_avinue *mt) {
vocabulary_entry **words;
int no_words;
Text__Words__as_array(&wa, &words, &no_words);
if (no_words == 0) return wa;
char suffixed[MAX_WORD_LENGTH*2];
char *initial_text = Text__Vocabulary__get_exemplar(words[0], FALSE);
int s = suffix_inflection(mt, suffixed, initial_text, MAX_WORD_LENGTH);
if (s == FALSE)
Extensions__IDs__truncated_strcpy(suffixed, initial_text, MAX_WORD_LENGTH+1);
int w1 = lexer_wordcount;
Text__feed_into_lexer(suffixed, FALSE, NULL);
int w2 = lexer_wordcount - 1;
Text__Words__truncate(&wa, 1);
return Text__Words__join(Text__Words__from_range(w1, w2), wa);
}
#line 434 "inform7/Chapter 5/Tries and Inflections.w"
match_avinue *indef_trie = NULL;
void Text__Inflections__preface_by_article(OUTPUT_STREAM, STREAM *TEMP) {
char *initial_text = STREAM_TEXT(TEMP);
if (indef_trie == NULL)
indef_trie =
Text__Languages__define_trie(singular_noun_to_its_indefinite_article_NTM, TRIE_START, NULL);
char *result = search_avinue(indef_trie, initial_text);
if (result == NULL) result = "a";
WRITE("%s ", result);
STREAM_COPY(OUT, TEMP);
}
#line 452 "inform7/Chapter 5/Tries and Inflections.w"
int Text__Inflections__pluralize(char *to, char *from, int max_length, natural_language *nl) {
if (nl == NULL) nl = English_language;
match_avinue *plural_trie =
Text__Languages__define_trie(singular_noun_to_its_plural_NTM, TRIE_END, nl);
return suffix_inflection(plural_trie, to, from, max_length);
}
#line 464 "inform7/Chapter 5/Tries and Inflections.w"
match_avinue *past_trie = NULL;
int pasturise_participle(char *to, char *from, int max_length) {
if (past_trie == NULL)
past_trie =
Text__Languages__define_trie(pasturise_participle_NTM, TRIE_START, NULL);
return suffix_inflection(past_trie, to, from, max_length);
}
#line 476 "inform7/Chapter 5/Tries and Inflections.w"
void Text__Inflections__test_tries(OUTPUT_STREAM, char *p) {
WRITE("Articled form: ");
TEMPORARY_STREAM;
STREAM_WRITE(TEMP, "%s", p);
Text__Inflections__preface_by_article(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
WRITE("\n");
WRITE(" - Plural form: ");
char recipient[128];
Text__Inflections__pluralize(recipient, p, 128, English_language);
WRITE("%s\n", recipient);
WRITE(" - Pasturised form: ");
pasturise_participle(recipient, p, 128);
WRITE("%s\n", recipient);
}
void Text__Inflections__add_to_avinue(match_avinue *mt, char *from, char *to) {
if ((mt == NULL) || (mt->the_trie == NULL)) internal_error("null trie");
search_trie(mt->the_trie, from, to);
}
#line 503 "inform7/Chapter 5/Tries and Inflections.w"
void Text__make_past_of_participle(int w1, int w2, int *plw1, int *plw2) {
char pasturised[2*MAX_WORD_LENGTH+1];
int i;
*plw1 = lexer_wordcount;
i = w1;
while (i <= w2) {
if (*(Text__word_text(i)) == '\"') strcpy(pasturised, "some-long-text");
else {
if (pasturise_participle(pasturised,
Text__word_text(i), 2*MAX_WORD_LENGTH)) {
if (i > w1) Text__splice_words(w1, i-1);
Text__feed_into_lexer(pasturised, FALSE, NULL);
if (i < w2) Text__splice_words(i+1, w2);
break;
}
}
i++;
}
*plw2 = lexer_wordcount-1;
LOGIF(CONSTRUCTED_PAST_PARTICIPLES,
"[Past participle of $W is $W]\n", w1, w2, *plw1, *plw2);
}
void Text__set_past_participle(int *past_w1, int *past_w2, int irregular_pp) {
int w1 = lexer_wordcount;
Text__splice_words(irregular_pp, irregular_pp);
if (*past_w1 < *past_w2) Text__splice_words(*past_w1 + 1, *past_w2);
*past_w1 = w1;
*past_w2 = lexer_wordcount-1;
}
#line 540 "inform7/Chapter 5/Tries and Inflections.w"
int Text__make_comparative(int w1) {
char comprised[MAX_WORD_LENGTH+3];
int pw1 = lexer_wordcount;
if (*(Text__word_text(w1)) == '\"') strcpy(comprised, "some-long-text");
else strcpy(comprised, Text__word_text(w1));
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");
Text__feed_into_lexer(comprised, FALSE, NULL);
strcpy(comprised, " than ");
Text__feed_into_lexer(comprised, FALSE, NULL);
int pw2 = lexer_wordcount-1;
LOGIF(CONSTRUCTED_PLURALS, "[Comparative of $W is $W]\n", w1, w1, pw1, pw2);
return pw1;
}
int Text__make_superlative(int w1) {
char comprised[MAX_WORD_LENGTH+3];
if (*(Text__word_text(w1)) == '\"') strcpy(comprised, "some-long-text");
else strcpy(comprised, Text__word_text(w1));
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");
Text__feed_into_lexer(comprised, FALSE, NULL);
LOGIF(CONSTRUCTED_PLURALS, "[Superlative of $W is $W]\n", w1, w1, lexer_wordcount-1, lexer_wordcount-1);
return lexer_wordcount-1;
}
#line 578 "inform7/Chapter 5/Tries and Inflections.w"
int Text__make_quiddity(int w1) {
char comprised[MAX_WORD_LENGTH+3];
if (*(Text__word_text(w1)) == '\"') strcpy(comprised, "some-long-text");
else strcpy(comprised, Text__word_text(w1));
if (comprised[Platform__strlen(comprised)-1] == 'y')
comprised[Platform__strlen(comprised)-1] = 'i';
strcat(comprised, "ness");
Text__feed_into_lexer(comprised, FALSE, NULL);
LOGIF(CONSTRUCTED_PLURALS, "[Quiddity of $W is $W]\n", w1, w1, lexer_wordcount-1, lexer_wordcount-1);
return lexer_wordcount-1;
}
#line 593 "inform7/Chapter 5/Tries and Inflections.w"
void test_trie_cases(OUTPUT_STREAM) {
test_trie_case("bi");
test_trie_case("bit");
test_trie_case("big");
test_trie_case("bigs");
test_trie_case("biggy");
test_trie_case("bigger");
test_trie_case("biggi");
test_trie_case("biggish");
test_trie_case("biggistical");
match_avinue *T =
Text__Languages__define_trie(small_trie_test_NTM, TRIE_START, English_language);
Text__Inflections__log_avinue(T);
}
void test_trie_case(char *t) {
match_avinue *T =
Text__Languages__define_trie(small_trie_test_NTM, TRIE_START, English_language);
char *res = search_avinue(T, t);
LOG("Test search on %s --> %s\n", t, (res == NULL)?"NO":res);
}
#line 618 "inform7/Chapter 5/Tries and Inflections.w"
int small_trie_test_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 624 "inform7/Chapter 5/Tries and Inflections.w"
#line 32 "inform7/Chapter 5/Word Assemblages.w"
word_assemblage wa_new(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 5/Word Assemblages.w"
word_assemblage Text__Words__from_range(int w1, int w2) {
if ((w1 < 0) || (w2-w1+1 > MAX_WORDS_IN_ASSEMBLAGE)) internal_error("assemblage overflow");
word_assemblage wa = wa_new();
int i;
for (i=w1; i<=w2; i++)
wa.indiv_words[wa.no_indiv_words++] = Text__word(i);
return wa;
}
#line 55 "inform7/Chapter 5/Word Assemblages.w"
word_assemblage Text__Words__lit_0(void) {
return wa_new();
}
word_assemblage Text__Words__lit_1(vocabulary_entry *ve1) {
word_assemblage wa = wa_new();
if (ve1) wa.indiv_words[wa.no_indiv_words++] = ve1;
return wa;
}
#line 68 "inform7/Chapter 5/Word Assemblages.w"
word_assemblage Text__Words__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 = wa_new();
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 5/Word Assemblages.w"
void Text__Words__to_range(word_assemblage *wa, int *w1, int *w2) {
if (wa->no_indiv_words == 0) { *w1 = -1; *w2 = -1; }
else {
*w1 = lexer_wordcount;
int i;
for (i=0; i<wa->no_indiv_words; i++) {
char str[MAX_WORD_LENGTH+2];
sprintf(str, " ");
strcpy(str+Platform__strlen(str), Text__Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
sprintf(str+Platform__strlen(str), " ");
Text__feed_into_lexer(str, FALSE, NULL);
}
*w2 = lexer_wordcount - 1;
}
}
#line 103 "inform7/Chapter 5/Word Assemblages.w"
void Text__Words__truncate(word_assemblage *wa, int n) {
if (n <= wa->no_indiv_words) {
int i;
for (i=0; i+n < wa->no_indiv_words; i++)
wa->indiv_words[i] = wa->indiv_words[i+n];
wa->no_indiv_words -= n;
}
}
void Text__Words__truncate_to(word_assemblage *wa, int n) {
if (n <= wa->no_indiv_words) {
wa->no_indiv_words = n;
}
}
#line 121 "inform7/Chapter 5/Word Assemblages.w"
int Text__Words__nonempty(word_assemblage wa1) {
if (wa1.no_indiv_words > 0) return TRUE;
return FALSE;
}
void Text__Words__copy_to_stream(OUTPUT_STREAM, word_assemblage *wa) {
int i;
for (i=0; i<wa->no_indiv_words; i++) {
if (i > 0) WRITE(" ");
WRITE("%s", Text__Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
}
}
void Text__Words__copy_to_string(word_assemblage *wa, char *str) {
str[0] = 0;
int i;
for (i=0; i<wa->no_indiv_words; i++) {
if (i > 0) strcpy(str+Platform__strlen(str), " ");
strcpy(str+Platform__strlen(str), Text__Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
}
}
vocabulary_entry *Text__Words__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), Text__Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
}
sprintf(str+Platform__strlen(str), " ");
int wn = lexer_wordcount;
Text__feed_into_lexer(str, FALSE, NULL);
return Text__word(wn);
}
void Text__Words__as_array(word_assemblage *wa, vocabulary_entry ***array, int *len) {
*array = wa->indiv_words;
*len = wa->no_indiv_words;
}
#line 166 "inform7/Chapter 5/Word Assemblages.w"
int Text__Words__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;
int i;
for (i=0; i<wa1->no_indiv_words; i++)
if (wa1->indiv_words[i] != wa2->indiv_words[i])
return FALSE;
return TRUE;
}
int Text__Words__compare_with_range(word_assemblage *wa, int w1, int w2) {
if (wa == NULL) return FALSE;
if ((w1 < 0) || (w2 < w1)) return FALSE;
if (wa->no_indiv_words != w2 - w1 + 1) return FALSE;
int i;
for (i=0; i<wa->no_indiv_words; i++)
if (wa->indiv_words[i] != Text__word(w1 + i))
return FALSE;
return TRUE;
}
#line 191 "inform7/Chapter 5/Word Assemblages.w"
int Text__Words__parse_as_strictly_initial_text(int w1, int w2, word_assemblage *wa) {
return Text__Words__parse_as_weakly_initial_text(w1, w2, wa, -1, -1, TRUE, FALSE);
}
int Text__Words__parse_as_weakly_initial_text(int w1, int w2, word_assemblage *wa,
int str1, int str2, int allow_uuc, int allow_to_fill) {
int k, i;
for (i=0, k=w1; i<wa->no_indiv_words; i++)
if ((wa->indiv_words[i] == PARBREAK_V) && (str1 >= 0)) {
if (k + str2 - str1 > w2) return -1;
if (Text__compare_word_range(str1, str2, k, k + str2 - str1) == FALSE) return -1;
k += str2 - str1 + 1;
} else if (wa->indiv_words[i]) {
if ((k > w2) || (wa->indiv_words[i] != Text__word(k))) return -1;
if ((allow_uuc == FALSE) && (Text__unexpectedly_upper_case(k))) return -1;
k++;
}
if ((k > w2) && (allow_to_fill == FALSE)) return -1;
return k;
}
#line 215 "inform7/Chapter 5/Word Assemblages.w"
vocabulary_entry *Text__Words__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 *Text__Words__first_word(word_assemblage *wa) {
if ((wa == NULL) || (wa->no_indiv_words == 0)) return NULL;
return wa->indiv_words[0];
}
#line 228 "inform7/Chapter 5/Word Assemblages.w"
void Text__Words__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", Text__Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
}
}
void Text__Words__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 ", Text__Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
}
}
#line 60 "inform7/Chapter 5/Clusters.w"
cluster *Text__Clusters__new(void) {
cluster *names = CREATE(cluster);
names->first_name = NULL;
return names;
}
#line 69 "inform7/Chapter 5/Clusters.w"
individual_name *Text__Clusters__add(cluster *names,
int w1, int w2, natural_language *foreign_language, int gender, int number, int pluralise) {
individual_name *in = CREATE(individual_name);
in->principal_meaning = NULL;
in->word_ref1 = w1; in->word_ref2 = w2;
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 97 "inform7/Chapter 5/Clusters.w"
plural_dictionary_entry *pde = NULL;
int k = 0;
do {
k++;
int plw1 = -1, plw2 = -1;
pde = make_plural_of(w1, w2, &plw1, &plw2, pde, foreign_language);
if (plw1 >= 0) {
LOGIF(CONSTRUCTED_PLURALS, "(%d) Reading plural of <$W> as <$W>\n", k,
w1, w2, plw1, plw2);
Text__Clusters__add(names, plw1, plw2, foreign_language, gender, 2, FALSE);
}
} while (pde);
}
#line 86 "inform7/Chapter 5/Clusters.w"
;
return in;
}
#line 120 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__add_with_agreements(cluster *cl, int w1, int w2, natural_language *nl) {
if (nl == NULL) nl = language_of_source_text;
if (nl == NULL) nl = English_language;
if (nl == English_language) {
Text__Clusters__add(cl, w1, w2, nl, NEUTER_GENDER, 1, FALSE);
} else {
int gna;
for (gna = 0; gna < 6; gna++)
{
#line 136 "inform7/Chapter 5/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;
}
int fw1 = w1, fw2 = w2;
{
#line 161 "inform7/Chapter 5/Clusters.w"
word_assemblage wa = Text__Words__from_range(w1, w2);
if (step1)
wa = Text__Inflections__apply_trie_to_wa(wa,
Text__Languages__define_trie(step1, TRIE_END, nl));
if (step2)
wa = Text__Inflections__apply_trie_to_wa(wa,
Text__Languages__define_trie(step2, TRIE_END, nl));
Text__Words__to_range(&wa, &fw1, &fw2);
}
#line 154 "inform7/Chapter 5/Clusters.w"
;
Text__Clusters__add(cl, fw1, fw2, nl, form_gender, form_number, FALSE);
}
#line 128 "inform7/Chapter 5/Clusters.w"
;
}
}
#line 178 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__set_plural_name(cluster *cl, int pw1, int pw2) {
individual_name *in;
for (in = cl->first_name; in; in = in->next)
if (in->name_number == 2) {
in->word_ref1 = pw1; in->word_ref2 = pw2;
return;
}
Text__Clusters__add(cl, pw1, pw2, NULL, NEUTER_GENDER, 2, FALSE);
}
#line 196 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__get_name(cluster *cl, int *w1, int *w2, int plural_flag) {
*w1 = -1; *w2 = -1;
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) {
*w1 = in->word_ref1; *w2 = in->word_ref2;
return;
}
}
#line 212 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__get_name_in_play(cluster *cl, int *w1, int *w2, int plural_flag) {
*w1 = -1; *w2 = -1;
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)) {
*w1 = in->word_ref1; *w2 = in->word_ref2;
return;
}
Text__Clusters__get_name(cl, w1, w2, plural_flag);
}
#line 229 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__get_name_general(cluster *cl, int *w1, int *w2,
natural_language *nl, int number_sought, int gender_sought) {
*w1 = -1; *w2 = -1;
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)) {
*w1 = in->word_ref1; *w2 = in->word_ref2;
return;
}
}
#line 248 "inform7/Chapter 5/Clusters.w"
void Text__Clusters__set_principal_meaning(individual_name *in, excerpt_meaning *em) {
if (in == NULL) internal_error("no individual name");
in->principal_meaning = em;
}
excerpt_meaning *Text__Clusters__get_principal_meaning(cluster *cl) {
if (cl->first_name == NULL) return NULL;
return cl->first_name->principal_meaning;
}
#line 268 "inform7/Chapter 5/Clusters.w"
sentence_handler PLURAL_SH_handler =
{ SENTENCE_NT, PLURAL_VB, 1, handle_plural_definition };
void handle_plural_definition(parse_node *p) {
/* do nothing: these sentences have already been caught by the traverse below */
}
void Text__traverse_for_plural_definitions(void) {
parse_node *p, *prevp;
for (prevp=NULL, TREE_START(p); p; prevp=p, TREE_NEXT(p)) {
if ((Parser__Nodes__type(p) == SENTENCE_NT)
&& (p->down)
&& (Parser__Nodes__int_annotation(p->down, verb_id_ANNOT) == PLURAL_VB)
&& (p->down->next) && (p->down->next->next))
register_plural_form(p->down->next->word_ref1,
p->down->next->word_ref2,
p->down->next->next->word_ref1,
p->down->next->next->word_ref2);
}
}
#line 294 "inform7/Chapter 5/Clusters.w"
void register_plural_form(int sing_w1, int sing_w2, int pl_w1, int pl_w2) {
plural_dictionary_entry *pde = CREATE(plural_dictionary_entry);
pde->singular_w1 = sing_w1;
pde->singular_w2 = sing_w2;
pde->plural_form_w1 = pl_w1;
pde->plural_form_w2 = pl_w2;
{
#line 311 "inform7/Chapter 5/Clusters.w"
int i;
for (i=sing_w1; i<=sing_w2; i++)
if (Text__Vocabulary__test_flags(i, TEXT_MC+TEXTWITHSUBS_MC)) {
Problems__sentence_problem(_P_(C5PluralOfQuoted),
"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;
}
for (i=pl_w1; i<=pl_w2; i++)
if (Text__Vocabulary__test_flags(i, TEXT_MC+TEXTWITHSUBS_MC)) {
Problems__sentence_problem(_P_(C5PluralIsQuoted),
"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 302 "inform7/Chapter 5/Clusters.w"
;
LOGIF(CONSTRUCTED_PLURALS, "[Registering plural of $W as $W]\n", sing_w1, sing_w2, pl_w1, pl_w2);
}
#line 341 "inform7/Chapter 5/Clusters.w"
plural_dictionary_entry *make_plural_of(int w1, int w2, int *plw1, int *plw2,
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 ((w1 == -1) || (w2 < w1)) { *plw1 = -1; *plw2 = -1; 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 (Text__compare_word_range(w1, w2, pde->singular_w1, pde->singular_w2)) {
*plw1 = pde->plural_form_w1;
*plw2 = pde->plural_form_w2;
return pde;
}
}
{
#line 378 "inform7/Chapter 5/Clusters.w"
*plw1 = lexer_wordcount;
if (w1<w2) Text__splice_words(w1, w2-1);
if (*(Text__word_text(w2)) == '\"') strcpy(pluralised, "some-long-text");
else Text__Inflections__pluralize(pluralised, Text__word_raw_text(w2), 2*MAX_WORD_LENGTH, nl);
Text__feed_into_lexer(pluralised, FALSE, NULL);
*plw2 = lexer_wordcount-1;
LOGIF(CONSTRUCTED_PLURALS, "[Constructing plural of $W as $W]\n", w1, w2, *plw1, *plw2);
}
#line 361 "inform7/Chapter 5/Clusters.w"
;
return NULL;
}
#line 96 "inform7/Chapter 5/Natural Languages.w"
int bundle_scan_made = FALSE;
void Text__Languages__scan(void) {
if (bundle_scan_made == FALSE) {
bundle_scan_made = TRUE;
{
#line 112 "inform7/Chapter 5/Natural Languages.w"
/* lowest priority: folder built into Inform application */
char built_in_bundles[MAX_FILENAME_LENGTH];
sprintf(built_in_bundles, "%s%cReserved%cLanguages",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
scan_bundles_from(built_in_bundles, "built in");
/* middle priority: the user's folder for installed extensions */
scan_bundles_from(pathname_of_languages, "installed");
/* highest priority: the Materials folder for the current project */
char materials_folder_bundles[MAX_FILENAME_LENGTH];
sprintf(materials_folder_bundles, "%s%cLanguages",
materials_folder, FOLDER_SEPARATOR);
scan_bundles_from(materials_folder_bundles, "from .materials");
}
#line 101 "inform7/Chapter 5/Natural Languages.w"
;
{
#line 193 "inform7/Chapter 5/Natural Languages.w"
natural_language *nl;
LOOP_OVER(nl, natural_language) {
int w1 = -1, w2 = -1;
{
#line 206 "inform7/Chapter 5/Natural Languages.w"
char info_file[MAX_FILENAME_LENGTH];
sprintf(info_file, "%s%cabout.txt", nl->nl_bundle_path, FOLDER_SEPARATOR);
FILE *ABOUT = Platform__iso_fopen(info_file, "r");
if (ABOUT == NULL) {
LOG("Can't find %s\n", info_file);
} else {
char line_buffer[MAX_BUNDLE_ABOUT_LINE_LENGTH+1];
w1 = lexer_wordcount;
while (TRUE) {
int len = Files__truncated_iso_fgets(ABOUT, line_buffer,
MAX_BUNDLE_ABOUT_LINE_LENGTH);
if (len < 0) break;
strcat(line_buffer, "\n");
Text__feed_into_lexer(line_buffer, FALSE, NULL);
}
w2 = lexer_wordcount - 1;
fclose(ABOUT);
}
}
#line 196 "inform7/Chapter 5/Natural Languages.w"
;
if (w1 >= 0)
{
#line 230 "inform7/Chapter 5/Natural Languages.w"
int n, rn = -1;
for (n = w1; n <= w2; n++) {
vocabulary_entry *ve = Text__word(n);
if (ve == PARBREAK_V) break;
int i = -1;
if ((ve) && (Text__Vocabulary__test_vflags(ve, NUMBER_MC)))
i = Text__Vocabulary__get_literal_number_value(ve);
if ((i >= 1) && (i < MAX_LANGUAGE_FIELDS)) {
if (rn >= 0) nl->language_field_w2[rn] = n-1;
rn = i; nl->language_field_w1[rn] = n+1;
}
}
if (rn >= 0) nl->language_field_w2[rn] = n-1;
}
#line 197 "inform7/Chapter 5/Natural Languages.w"
;
}
}
#line 102 "inform7/Chapter 5/Natural Languages.w"
;
}
}
#line 131 "inform7/Chapter 5/Natural Languages.w"
void scan_bundles_from(char *pathname, char *origin) {
TEMPORARY_STREAM;
int s = Files__Folders__write_contents_to_stream(TEMP, pathname);
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 154 "inform7/Chapter 5/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 = Text__Languages__get_nl(entry);
if (nl == NULL)
{
#line 171 "inform7/Chapter 5/Natural Languages.w"
nl = CREATE(natural_language);
char sentence_format[MAX_FILENAME_LENGTH + 20];
sprintf(sentence_format, "%s language\n", entry);
nl->word_ref1 = lexer_wordcount;
Text__feed_into_lexer(sentence_format, FALSE, STANDARD_PUNCTUATION_MARKS);
nl->word_ref2 = lexer_wordcount-1;
nl->nl_instance = NULL;
nl->extension_required = FALSE;
nl->adaptive_person = -1; /* i.e., none yet specified */
int n;
for (n=0; n<MAX_LANGUAGE_FIELDS; n++) {
nl->language_field_w1[n] = -1;
nl->language_field_w2[n] = -1;
}
}
#line 163 "inform7/Chapter 5/Natural Languages.w"
;
sprintf(nl->nl_bundle_path, "%s%c%s", pathname, FOLDER_SEPARATOR, entry);
LOG("Found language bundle '%s' (%s)\n", entry, origin);
}
}
#line 141 "inform7/Chapter 5/Natural Languages.w"
;
entry_start = i+1;
}
}
{
#line 154 "inform7/Chapter 5/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 = Text__Languages__get_nl(entry);
if (nl == NULL)
{
#line 171 "inform7/Chapter 5/Natural Languages.w"
nl = CREATE(natural_language);
char sentence_format[MAX_FILENAME_LENGTH + 20];
sprintf(sentence_format, "%s language\n", entry);
nl->word_ref1 = lexer_wordcount;
Text__feed_into_lexer(sentence_format, FALSE, STANDARD_PUNCTUATION_MARKS);
nl->word_ref2 = lexer_wordcount-1;
nl->nl_instance = NULL;
nl->extension_required = FALSE;
nl->adaptive_person = -1; /* i.e., none yet specified */
int n;
for (n=0; n<MAX_LANGUAGE_FIELDS; n++) {
nl->language_field_w1[n] = -1;
nl->language_field_w2[n] = -1;
}
}
#line 163 "inform7/Chapter 5/Natural Languages.w"
;
sprintf(nl->nl_bundle_path, "%s%c%s", pathname, FOLDER_SEPARATOR, entry);
LOG("Found language bundle '%s' (%s)\n", entry, origin);
}
}
#line 145 "inform7/Chapter 5/Natural Languages.w"
;
}
CLOSE_TEMPORARY_STREAM;
}
#line 250 "inform7/Chapter 5/Natural Languages.w"
natural_language *Text__Languages__get_nl(char *name) {
Text__Languages__scan();
natural_language *nl;
LOOP_OVER(nl, natural_language) {
char *p = Text__word_text(nl->word_ref1);
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 267 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__log(natural_language *nl) {
if (nl == NULL) { LOG("<null-language>"); }
else { LOG("%s", Text__Languages__get_name(nl)); }
}
#line 275 "inform7/Chapter 5/Natural Languages.w"
char *Text__Languages__get_name(natural_language *nl) {
if (nl == NULL) nl = English_language;
return Text__word_raw_text(nl->word_ref1);
}
#line 286 "inform7/Chapter 5/Natural Languages.w"
int natural_language_NTMR(int w1, int w2, int *X, void **XP) {
#line 287 "inform7/Chapter 5/Natural Languages.w"
natural_language *nl;
LOOP_OVER(nl, natural_language) {
if ((w1 == w2) && (Text__word(nl->word_ref1) == Text__word(w1))) {
*XP = nl; return TRUE;
}
}
return FALSE;
}
#line 307 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__stock_nl_kind(kind *K) {
natural_language *nl;
LOOP_OVER(nl, natural_language) {
pcalc_prop *prop =
Calculus__Propositions__to_create_something(K, nl->word_ref1, nl->word_ref2);
Calculus__Propositions__assert_true(prop, CERTAIN_CE);
nl->nl_instance = latest_instance;
}
}
#line 328 "inform7/Chapter 5/Natural Languages.w"
int Text__Languages__adaptive_person(natural_language *nl) {
if ((nl->adaptive_person == -1) && (P_adaptive_text_viewpoint)) {
instance *I = nl->nl_instance;
specification *spec = World__Inferences__get_prop_state(
Data__Instances__as_subject(I), P_adaptive_text_viewpoint);
if (Specifications__Values__is_actual_CONSTANT(spec)) {
instance *V = RETRIEVE_FROM_SPEC(spec, instance);
nl->adaptive_person = Data__Instances__get_numerical_value(V)-1;
}
}
if (nl->adaptive_person == -1) return FIRST_PERSON_PLURAL;
return nl->adaptive_person;
}
#line 346 "inform7/Chapter 5/Natural Languages.w"
natural_language *Text__Languages__English(void) {
natural_language *nl = Text__Languages__get_nl("english");
if (nl == NULL) internal_error("unable to find English language bundle");
nl->extension_required = TRUE;
English_language = nl;
return nl;
}
void Text__Languages__set_language_of_play(natural_language *nl) {
language_of_play = nl;
if (nl) nl->extension_required = TRUE;
}
#line 365 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__write_language_code(OUTPUT_STREAM, natural_language *nl) {
if (nl == NULL) nl = English_language;
int t1 = nl->language_field_w1[ISO_639_CODE_LFIELD],
t2 = nl->language_field_w2[ISO_639_CODE_LFIELD];
if (t1 >= 0) Text__print_raw_text_to_stream(t1, t2, OUT);
else WRITE("en");
}
#line 385 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__include_required(void) {
natural_language *nl;
int w1 = lexer_wordcount;
int icount = 0;
LOOP_OVER(nl, natural_language)
if (nl->extension_required) {
TEMPORARY_STREAM;
if (icount++ > 0) STREAM_WRITE(TEMP, ". ");
STREAM_WRITE(TEMP, "Include %s Language by ",
Text__Languages__get_name(nl));
int t1 = nl->language_field_w1[TRANSLATOR_LFIELD],
t2 = nl->language_field_w2[TRANSLATOR_LFIELD];
if (t1 >= 0) Text__print_raw_text_to_stream(t1, t2, TEMP);
else STREAM_WRITE(TEMP, "Unknown Translator");
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
CLOSE_TEMPORARY_STREAM;
}
Parser__Sentences__break(w1, lexer_wordcount-1, NULL, first_extension_inclusion);
}
#line 411 "inform7/Chapter 5/Natural Languages.w"
void Text__Languages__load_preform(natural_language *nl) {
if (nl == NULL) internal_error("can't load preform from null language");
char filename_of_preform[MAX_FILENAME_LENGTH];
sprintf(filename_of_preform, "%s%cSyntax.preform",
nl->nl_bundle_path, FOLDER_SEPARATOR);
LOG("Reading language definition from <%s>\n", filename_of_preform);
FILE *PREFORM = Platform__iso_fopen(filename_of_preform, "r");
if (PREFORM == NULL) internal_error("Unable to open Preform definition");
char line_buffer[MAX_PREFORM_LINE_LENGTH+1];
while (TRUE) {
int len = Files__truncated_iso_fgets(PREFORM, line_buffer, MAX_PREFORM_LINE_LENGTH);
if (len < 0) break;
strcat(line_buffer, "\n");
Text__feed_into_lexer(line_buffer, FALSE, PREFORM_PUNCTUATION_MARKS);
}
fclose(PREFORM);
}
#line 377 "inform7/Chapter 5/Preform.w"
void Text__Languages__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: ", Text__Vocabulary__get_exemplar(nt->nonterminal_id, FALSE));
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(" "); Text__Languages__log_production(pr, detailed);
#ifdef INSTRUMENTED_PREFORM
LOG(" %d/%d: ", pr->production_matches, pr->production_tries);
if (pr->sample_w1 >= 0) LOG("<$W>", pr->sample_w1, pr->sample_w2);
if (pr->sample_sentence)
LOG(" in <$W>",
pr->sample_sentence->word_ref1, pr->sample_sentence->word_ref2);
#endif
LOG(" ==> ");
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 416 "inform7/Chapter 5/Preform.w"
void Text__Languages__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) {
log_ptoken(pt, detailed);
LOG(" ");
}
}
#line 428 "inform7/Chapter 5/Preform.w"
void 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", Text__Vocabulary__get_exemplar(alt->nt_pt->nonterminal_id, FALSE));
if (detailed) LOG("=%d", alt->result_index);
} else {
LOG("%s", Text__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 450 "inform7/Chapter 5/Preform.w"
void Text__Languages__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", Text__Vocabulary__get_exemplar(alt->nt_pt->nonterminal_id, FALSE));
} else {
WRITE("%s", Text__Vocabulary__get_exemplar(alt->ve_pt, FALSE));
}
if (alt->alternative_ptoken) WRITE("/");
}
if (pt->range_ends >= 0) WRITE("}");
}
#line 471 "inform7/Chapter 5/Preform.w"
int preform_nonterminal_NTMR(int w1, int w2, int *X, void **XP) {
#line 472 "inform7/Chapter 5/Preform.w"
nonterminal *nt = find_nonterminal(Text__word(w1));
if (nt) { *XP = nt; return TRUE; }
return FALSE;
}
#line 480 "inform7/Chapter 5/Preform.w"
void Text__Languages__watch(nonterminal *nt, int state) {
nt->watched = state;
}
#line 489 "inform7/Chapter 5/Preform.w"
vocabulary_entry *AMPERSAND_V;
vocabulary_entry *BACKSLASH_V;
vocabulary_entry *CARET_V;
vocabulary_entry *COLONCOLONEQUALS_V;
vocabulary_entry *QUESTIONMARK_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 505 "inform7/Chapter 5/Preform.w"
void Text__Languages__read_definition(void) {
{
#line 539 "inform7/Chapter 5/Preform.w"
CAPITAL_K_V = Text__Vocabulary__entry_for_text("k");
CAPITAL_L_V = Text__Vocabulary__entry_for_text("l");
CLOSEBRACE_V = Text__Vocabulary__entry_for_text("}");
CLOSEBRACKET_V = Text__Vocabulary__entry_for_text(")");
COLON_V = Text__Vocabulary__entry_for_text(":");
COMMA_V = Text__Vocabulary__entry_for_text(",");
DOUBLEDASH_V = Text__Vocabulary__entry_for_text("--");
FORWARDSLASH_V = Text__Vocabulary__entry_for_text("/");
FULLSTOP_V = Text__Vocabulary__entry_for_text(".");
OPENBRACE_V = Text__Vocabulary__entry_for_text("{");
OPENBRACKET_V = Text__Vocabulary__entry_for_text("(");
OPENI6_V = Text__Vocabulary__entry_for_text("(-");
PARBREAK_V = Text__Vocabulary__entry_for_text(PARAGRAPH_BREAK);
SEMICOLON_V = Text__Vocabulary__entry_for_text(";");
STROKE_V = Text__Vocabulary__entry_for_text("|");
}
#line 506 "inform7/Chapter 5/Preform.w"
;
{
#line 559 "inform7/Chapter 5/Preform.w"
register_tangled_nonterminals();
;
nonterminal *nt;
LOOP_OVER(nt, nonterminal)
if ((nt->marked_internal) && (nt->internal_definition == NULL))
internal_error("internal undefined");
}
#line 507 "inform7/Chapter 5/Preform.w"
;
{
#line 586 "inform7/Chapter 5/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 508 "inform7/Chapter 5/Preform.w"
;
AMPERSAND_V = Text__Vocabulary__entry_for_text("&");
BACKSLASH_V = Text__Vocabulary__entry_for_text("\\");
CARET_V = Text__Vocabulary__entry_for_text("^");
COLONCOLONEQUALS_V = Text__Vocabulary__entry_for_text(":" ":=");
QUESTIONMARK_V = Text__Vocabulary__entry_for_text("?");
SIXDOTS_V = Text__Vocabulary__entry_for_text("......");
THREEASTERISKS_V = Text__Vocabulary__entry_for_text("***");
THREEDOTS_V = Text__Vocabulary__entry_for_text("...");
THREEHASHES_V = Text__Vocabulary__entry_for_text("###");
UNDERSCORE_V = Text__Vocabulary__entry_for_text("_");
language_V = Text__Vocabulary__entry_for_text("language");
internal_V = Text__Vocabulary__entry_for_text("internal");
Text__Languages__scan();
int w1 = lexer_wordcount;
language_being_read_by_Preform = Text__Languages__English();
Text__Languages__load_preform(language_being_read_by_Preform);
int w2 = lexer_wordcount - 1;
int nonterminals_declared = Text__Languages__parse_preform(w1, w2, FALSE);
language_definition_top = lexer_wordcount - 1;
LOG("%d declarations read (%d words)\n", nonterminals_declared, w2 - w1 + 1);
}
#line 599 "inform7/Chapter 5/Preform.w"
int Text__Languages__parse_preform(int w1, int w2, int break_first) {
if (break_first) {
char *p = Text__word_raw_text(w1);
w1 = lexer_wordcount;
Text__feed_into_lexer(p, FALSE, PREFORM_PUNCTUATION_MARKS);
w2 = lexer_wordcount - 1;
}
int nonterminals_declared = 0, wn = w1;
while ((wn >= 0) && (wn <= w2)) {
if (Text__word(wn) == PARBREAK_V) { wn++; continue; }
if ((w2 >= wn+1) && (Text__word(wn) == language_V)) {
{
#line 634 "inform7/Chapter 5/Preform.w"
natural_language *nl = Text__Languages__get_nl(Text__word_text(wn+1));
if (nl == NULL) {
LOG("Missing: $W\n", wn+1, wn+1);
internal_error("tried to define for missing language");
}
language_being_read_by_Preform = nl;
}
#line 610 "inform7/Chapter 5/Preform.w"
;
wn += 2;
continue;
}
if ((w2 >= wn+1) && (Text__word(wn+1) == internal_V)) {
{
#line 644 "inform7/Chapter 5/Preform.w"
nonterminal *nt = find_nonterminal(Text__word(wn));
if (nt->first_production_list) internal_error("internal is defined");
nt->marked_internal = TRUE;
wn += 2;
}
#line 615 "inform7/Chapter 5/Preform.w"
;
nonterminals_declared++;
continue;
}
if ((w2 >= wn+2) && (Text__word(wn+1) == COLONCOLONEQUALS_V)) {
{
#line 653 "inform7/Chapter 5/Preform.w"
nonterminal *nt = find_nonterminal(Text__word(wn));
production_list *pl;
{
#line 671 "inform7/Chapter 5/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 685 "inform7/Chapter 5/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 679 "inform7/Chapter 5/Preform.w"
;
}
}
#line 655 "inform7/Chapter 5/Preform.w"
;
wn += 2;
int pc = 0;
while (TRUE) {
int x = wn;
while ((x <= w2) && (Text__word(x) != STROKE_V) && (Text__word(x) != PARBREAK_V)) x++;
production *pr = new_production(wn, x-1, nt, pc++);
wn = x;
{
#line 695 "inform7/Chapter 5/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 663 "inform7/Chapter 5/Preform.w"
;
if ((wn > w2) || (Text__word(x) == PARBREAK_V)) break; /* reached end */
wn++; /* advance past the stroke and continue */
}
}
#line 620 "inform7/Chapter 5/Preform.w"
;
nonterminals_declared++;
continue;
}
LOG("At: <$W>\n", wn, wn+10);
internal_error("language definition failed");
}
optimise_counts();
return nonterminals_declared;
}
#line 705 "inform7/Chapter 5/Preform.w"
nonterminal *find_nonterminal(vocabulary_entry *ve) {
nonterminal *nt;
LOOP_OVER(nt, nonterminal)
if (ve == nt->nonterminal_id)
return nt;
nt = CREATE(nonterminal);
nt->nonterminal_id = ve;
nt->voracious = 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;
int i;
for (i=0; i<MAX_RANGES_PER_PRODUCTION; i++) {
nt->range_result_w1[i] = -1;
nt->range_result_w2[i] = -1;
}
nt->watched = FALSE;
nt->nonterminal_tries = 0; nt->nonterminal_matches = 0;
return nt;
}
#line 741 "inform7/Chapter 5/Preform.w"
production *new_production(int w1, int w2, 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_w1 = -1; pr->sample_w2 = -1;
ptoken *head = NULL, *tail = NULL;
{
#line 768 "inform7/Chapter 5/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 i, tc = 0;
for (i = w1; i <= w2; i++) {
if (unescaped)
{
#line 793 "inform7/Chapter 5/Preform.w"
if (Text__word(i) == CARET_V) { negation_modifier = TRUE; continue; }
if (Text__word(i) == UNDERSCORE_V) { lower_case_modifier = TRUE; continue; }
if (Text__word(i) == BACKSLASH_V) { unescaped = FALSE; continue; }
switch (bracing_mode) {
case OUTSIDE_PTBRACE:
if (Text__word(i) == OPENBRACE_V) {
bracing_mode = ABOUT_TO_OPEN_PTBRACE; continue;
}
break;
case INSIDE_PTBRACE:
if (Text__word(i) == CLOSEBRACE_V) {
if (bracing_begins_at) {
int rnum = pr->no_ranges++;
if ((i+2 <= w2) && (Text__word(i+1) == QUESTIONMARK_V) &&
(Text__Vocabulary__test_flags(i+2, NUMBER_MC))) {
rnum = Text__Vocabulary__get_literal_number_value(Text__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 775 "inform7/Chapter 5/Preform.w"
;
ptoken *pt = 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 850 "inform7/Chapter 5/Preform.w"
if (result_count < MAX_RESULTS_PER_PRODUCTION) {
if ((i+2 <= w2) && (Text__word(i+1) == QUESTIONMARK_V) &&
(Text__Vocabulary__test_flags(i+2, NUMBER_MC))) {
pt->result_index = Text__Vocabulary__get_literal_number_value(Text__word(i+2));
i += 2;
} else {
pt->result_index = result_count;
}
result_count++;
}
}
#line 780 "inform7/Chapter 5/Preform.w"
;
{
#line 822 "inform7/Chapter 5/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 782 "inform7/Chapter 5/Preform.w"
;
if (tc++ < MAX_PTOKENS_PER_PRODUCTION) {
if (head == NULL) head = pt; else tail->next_ptoken = pt;
tail = pt;
}
}
}
#line 756 "inform7/Chapter 5/Preform.w"
;
pr->first_ptoken = head;
return pr;
}
#line 864 "inform7/Chapter 5/Preform.w"
ptoken *parse_slashed_chain(nonterminal *nt, production *pr, int wn, int unescaped) {
int a1 = wn, a2 = wn;
{
#line 875 "inform7/Chapter 5/Preform.w"
char *p = Text__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) {
a1 = lexer_wordcount;
Text__feed_into_lexer(p, FALSE, "/"); /* break only at slashes */
a2 = lexer_wordcount - 1;
}
}
#line 866 "inform7/Chapter 5/Preform.w"
;
ptoken *pt = NULL;
{
#line 899 "inform7/Chapter 5/Preform.w"
ptoken *alt = NULL;
for (; a1 <= a2; a1++)
if (Text__word(a1) != FORWARDSLASH_V) {
int mode = unescaped;
if (a2 > a1) mode = FALSE;
ptoken *latest = new_ptoken(Text__word(a1), mode, nt, pr->match_number);
if (alt == NULL) pt = latest;
else alt->alternative_ptoken = latest;
alt = latest;
}
}
#line 868 "inform7/Chapter 5/Preform.w"
;
return pt;
}
#line 918 "inform7/Chapter 5/Preform.w"
ptoken *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 = Text__Vocabulary__get_exemplar(ve, FALSE);
if ((unescaped) && (p) && (p[0] == '<') && (p[Platform__strlen(p)-1] == '>')) {
pt->nt_pt = 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 969 "inform7/Chapter 5/Preform.w"
int first_round_of_nt_optimisation_made = FALSE;
void optimise_counts(void) {
nonterminal *nt;
LOOP_OVER(nt, nonterminal) {
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) {
int wn;
for (wn = 0; wn < lexer_wordcount; wn++) {
if (Text__Vocabulary__test_flags(wn, NUMBER_MC))
Text__Languages__mark_as_cardinal(Text__word(wn));
if (Text__Vocabulary__test_flags(wn, ORDINAL_MC))
Text__Languages__mark_as_ordinal(Text__word(wn));
}
first_round_of_nt_optimisation_made = TRUE;
mark_nt_as_requiring_itself_conj(cardinal_number_NTM);
mark_nt_as_requiring_itself_conj(ordinal_number_NTM);
mark_nt_as_requiring_itself_first(general_verb_NTM);
mark_nt_as_requiring_itself_first(general_verb_present_positive_NTM);
mark_nt_as_requiring_itself_first(copular_verb_NTM);
mark_nt_as_requiring_itself_first(copular_verb_present_positive_NTM);
mark_nt_as_requiring_itself_first(negated_noncopular_verb_present_NTM);
mark_nt_as_requiring_itself_first(universal_verb_NTM);
mark_nt_as_requiring_itself_first(possession_verb_present_positive_NTM);
mark_nt_as_requiring_itself_first(negated_verb_NTM);
mark_nt_as_requiring_itself_first(past_tense_verb_NTM);
mark_nt_as_requiring_itself(preposition_NTM);
mark_nt_as_requiring_itself(preposition_implying_player_NTM);
mark_nt_as_requiring_itself_conj(s_adjective_NTM);
mark_nt_as_requiring_itself_articled(s_instance_name_NTM);
mark_nt_as_requiring_itself_articled(k_kind_variable_NTM);
mark_nt_as_requiring_itself_articled(k_formal_kind_variable_NTM);
mark_nt_as_requiring_itself_articled(k_base_kind_NTM);
mark_nt_as_requiring_itself_articled(k_kind_construction_NTM);
}
LOOP_OVER(nt, nonterminal) optimise_nt(nt);
LOOP_OVER(nt, nonterminal) optimise_nt_reqs(nt);
}
void optimise_nt(nonterminal *nt) {
if (nt->optimised_in_this_pass) return;
nt->optimised_in_this_pass = TRUE;
{
#line 1039 "inform7/Chapter 5/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;
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 1018 "inform7/Chapter 5/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 1079 "inform7/Chapter 5/Preform.w"
int posn = 1;
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
last = pt;
int L = 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 1025 "inform7/Chapter 5/Preform.w"
;
{
#line 1101 "inform7/Chapter 5/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 = 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 1026 "inform7/Chapter 5/Preform.w"
;
{
#line 1123 "inform7/Chapter 5/Preform.w"
pr->no_struts = 0;
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
if ((pt->ptoken_position == 0) && (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) && (ptoken_width(pt) != PTOKEN_ELASTIC)) {
pt->strut_number = pr->no_struts;
pr->strut_lengths[pr->no_struts] += ptoken_width(pt);
if (pt->next_ptoken == NULL) break; /* should be impossible */
pt = pt->next_ptoken;
}
pr->no_struts++;
}
}
}
#line 1027 "inform7/Chapter 5/Preform.w"
;
{
#line 1143 "inform7/Chapter 5/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 1028 "inform7/Chapter 5/Preform.w"
;
}
}
{
#line 1153 "inform7/Chapter 5/Preform.w"
int first_production = TRUE;
clear_rreq(&(nt->nonterminal_req));
if (nt == k_kind_NTM) mark_nt_as_requiring_itself_articled(nt); /* to break a horrible circularity */
if (nt == k_kind_of_kind_NTM) mark_nt_as_requiring_itself_articled(nt); /* to break a horrible circularity */
range_requirement nnt;
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)
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;
clear_rreq(&prt);
int all = TRUE, first = TRUE;
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
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)
set_nt_incidence(alt->ve_pt, nt);
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; */
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 {
concatenate_rreq(&prt, &(pt->token_req));
}
first = FALSE;
}
}
if (first_production) {
nnt = prt;
} else {
disjoin_rreq(&nnt, &prt);
}
first_production = FALSE;
pr->production_req = prt;
}
}
nt->nonterminal_req = nnt;
if (nt == k_kind_NTM) mark_nt_as_requiring_itself_articled(nt); /* to break a horrible circularity */
if (nt == k_kind_of_kind_NTM) mark_nt_as_requiring_itself_articled(nt); /* to break a horrible circularity */
}
#line 1031 "inform7/Chapter 5/Preform.w"
;
}
#line 1225 "inform7/Chapter 5/Preform.w"
void 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) {
optimise_req(&(pr->production_req), prev_req);
prev_req = &(pr->production_req);
}
}
optimise_req(&(nt->nonterminal_req), NULL);
}
void 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 1266 "inform7/Chapter 5/Preform.w"
void Text__Languages__mark_as_preposition(vocabulary_entry *ve) {
Text__Vocabulary__set_flags(ve, PREPOSITION_MC);
set_nt_incidence(ve, preposition_NTM);
set_nt_incidence(ve, preposition_implying_player_NTM);
}
void Text__Languages__mark_as_verb(vocabulary_entry *ve) {
set_nt_incidence(ve, general_verb_NTM);
set_nt_incidence(ve, general_verb_present_positive_NTM);
set_nt_incidence(ve, foreign_verb_present_positive_NTM);
set_nt_incidence(ve, copular_verb_NTM);
set_nt_incidence(ve, copular_verb_present_positive_NTM);
set_nt_incidence(ve, negated_noncopular_verb_present_NTM);
set_nt_incidence(ve, universal_verb_NTM);
set_nt_incidence(ve, possession_verb_present_positive_NTM);
set_nt_incidence(ve, negated_verb_NTM);
set_nt_incidence(ve, past_tense_verb_NTM);
}
void Text__Languages__mark_as_cardinal(vocabulary_entry *ve) {
set_nt_incidence(ve, cardinal_number_NTM);
}
void Text__Languages__mark_as_ordinal(vocabulary_entry *ve) {
set_nt_incidence(ve, ordinal_number_NTM);
}
void mark_nt_as_requiring_itself(nonterminal *nt) {
nt->nonterminal_req.DS_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.DW_req |= (nt_bitmap_bit(nt));
}
void mark_nt_as_requiring_itself_first(nonterminal *nt) {
nt->nonterminal_req.DS_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.DW_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.FS_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.FW_req |= (nt_bitmap_bit(nt));
}
void mark_nt_as_requiring_itself_conj(nonterminal *nt) {
nt->nonterminal_req.DS_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.DW_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.CS_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.CW_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.FS_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.FW_req |= (nt_bitmap_bit(nt));
}
void mark_nt_as_requiring_itself_articled(nonterminal *nt) {
nt->nonterminal_req.DS_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.DW_req |= (nt_bitmap_bit(nt));
nt->nonterminal_req.CW_req |= (nt_bitmap_bit(nt) + nt_bitmap_bit(article_NTM));
nt->nonterminal_req.FW_req |= (nt_bitmap_bit(nt) + nt_bitmap_bit(article_NTM));
}
void set_nt_incidence(vocabulary_entry *ve, nonterminal *nt) {
int R = Text__Vocabulary__get_ntb(ve);
R |= (nt_bitmap_bit(nt));
Text__Vocabulary__set_ntb(ve, R);
}
#line 1332 "inform7/Chapter 5/Preform.w"
int 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 Text__Languages__test_word(int wn, nonterminal *nt) {
int b = nt_bitmap_bit(nt);
if ((Text__Vocabulary__get_ntb(Text__word(wn))) & b) return TRUE;
return FALSE;
}
void Text__Languages__mark_word(int wn, nonterminal *nt) {
set_nt_incidence(Text__word(wn), nt);
}
void Text__Languages__mark_vocabulary(vocabulary_entry *ve, nonterminal *nt) {
set_nt_incidence(ve, nt);
}
int Text__Languages__test_vocabulary(vocabulary_entry *ve, nonterminal *nt) {
int b = nt_bitmap_bit(nt);
if ((Text__Vocabulary__get_ntb(ve)) & b) return TRUE;
return FALSE;
}
int get_range_disjunction(int w1, int w2) {
int R = 0, i;
for (i = w1; i <= w2; i++)
R |= Text__Vocabulary__get_ntb(Text__word(i));
return R;
}
int get_range_conjunction(int w1, int w2) {
int R = 0, i;
for (i = w1; i <= w2; i++) {
if (i == w1) R = Text__Vocabulary__get_ntb(Text__word(i));
else R &= Text__Vocabulary__get_ntb(Text__word(i));
}
return R;
}
#line 1400 "inform7/Chapter 5/Preform.w"
int nt_bitmap_violates(int w1, int w2, range_requirement *req) {
if (req->no_requirements) return FALSE;
if (w1 == w2) {
int bm = Text__Vocabulary__get_ntb(Text__word(w1));
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 i, disj = 0;
for (i = w1; i <= w2; i++) {
int bm = Text__Vocabulary__get_ntb(Text__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 == w1) && (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) {
int i;
for (i = w1; i <= w2; i++) {
int bm = Text__Vocabulary__get_ntb(Text__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 == w1) && (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 i, disj = 0;
for (i = w1; i <= w2; i++) {
int bm = Text__Vocabulary__get_ntb(Text__word(i));
disj |= bm;
if ((i == w1) && (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 = Text__Vocabulary__get_ntb(Text__word(w1));
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
}
return FALSE;
}
#line 1464 "inform7/Chapter 5/Preform.w"
void concatenate_rreq(range_requirement *req, range_requirement *with) {
req->DS_req = concatenate_ds(req->DS_req, with->DS_req);
req->DW_req = concatenate_dw(req->DW_req, with->DW_req);
req->CS_req = concatenate_cs(req->CS_req, with->CS_req);
req->CW_req = concatenate_cw(req->CW_req, with->CW_req);
req->FS_req = concatenate_fs(req->FS_req, with->FS_req);
req->FW_req = concatenate_fw(req->FW_req, with->FW_req);
}
#line 1479 "inform7/Chapter 5/Preform.w"
int concatenate_ds(int m1, int m2) {
return m1 | m2;
}
#line 1488 "inform7/Chapter 5/Preform.w"
int concatenate_cs(int m1, int m2) {
return m1 & m2;
}
#line 1499 "inform7/Chapter 5/Preform.w"
int 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 1510 "inform7/Chapter 5/Preform.w"
int 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 1519 "inform7/Chapter 5/Preform.w"
int concatenate_fs(int m1, int m2) {
return m1;
}
int concatenate_fw(int m1, int m2) {
return m1;
}
#line 1532 "inform7/Chapter 5/Preform.w"
void disjoin_rreq(range_requirement *req, range_requirement *with) {
req->DS_req = disjoin_ds(req->DS_req, with->DS_req);
req->DW_req = disjoin_dw(req->DW_req, with->DW_req);
req->CS_req = disjoin_cs(req->CS_req, with->CS_req);
req->CW_req = disjoin_cw(req->CW_req, with->CW_req);
req->FS_req = disjoin_fs(req->FS_req, with->FS_req);
req->FW_req = disjoin_fw(req->FW_req, with->FW_req);
}
#line 1547 "inform7/Chapter 5/Preform.w"
int disjoin_ds(int m1, int m2) {
return m1 & m2;
}
#line 1556 "inform7/Chapter 5/Preform.w"
int disjoin_cs(int m1, int m2) {
return m1 & m2;
}
#line 1565 "inform7/Chapter 5/Preform.w"
int 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 1574 "inform7/Chapter 5/Preform.w"
int 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 disjoin_fw(int m1, int m2) {
return disjoin_cw(m1, m2);
}
int disjoin_fs(int m1, int m2) {
return disjoin_cs(m1, m2);
}
void 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 atomic_rreq(range_requirement *req, nonterminal *nt) {
int b = 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 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 1615 "inform7/Chapter 5/Preform.w"
int ptoken_width(ptoken *pt) {
int min, max;
ptoken_extrema(pt, &min, &max);
if (min != max) return PTOKEN_ELASTIC;
return min;
}
#line 1629 "inform7/Chapter 5/Preform.w"
void 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:
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 1686 "inform7/Chapter 5/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 parse_nt_against_word_range(nonterminal *nt, int w1, int w2, int *result,
void **result_p) {
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",
Text__Vocabulary__get_exemplar(nt->nonterminal_id, FALSE), w1, w2);
}
}
int input_length = w2 - w1 + 1;
if ((nt->max_nt_words == 0) ||
((input_length >= nt->min_nt_words) && (input_length <= nt->max_nt_words))) {
{
#line 1745 "inform7/Chapter 5/Preform.w"
int unoptimised = FALSE;
if ((w1 > w2) || (w1 < 0) || (input_length >= RANGE_OPTIMISATION_LENGTH))
unoptimised = TRUE;
if (nt->internal_definition) {
if (nt->voracious) unoptimised = TRUE;
if ((unoptimised) || (nt_bitmap_violates(w1, w2, &(nt->nonterminal_req)) == FALSE)) {
int r, Q; void *QP = NULL;
if (w1 >= 0) r = (*(nt->internal_definition))(w1, w2, &Q, &QP);
else { r = FALSE; Q = 0; }
if (r) {
if (nt->voracious) success_rval = r;
if (ptraci) LOG("Succeeded\n");
{
#line 1730 "inform7/Chapter 5/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 1757 "inform7/Chapter 5/Preform.w"
;
}
} else {
if (ptraci) {
LOG("%s: <$W> violates ",
Text__Vocabulary__get_exemplar(nt->nonterminal_id, FALSE),
w1, w2);
log_range_requirement(&(nt->nonterminal_req));
LOG("\n");
}
}
} else {
if ((unoptimised) || (nt_bitmap_violates(w1, w2, &(nt->nonterminal_req)) == FALSE)) {
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 = nt_bitmap_violates(w1, w2, &(pr->production_req));
last_v = violates;
}
if (violates == FALSE) {
{
#line 1813 "inform7/Chapter 5/Preform.w"
if (ptraci) {
LOG_INDENT;
{
#line 1857 "inform7/Chapter 5/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 1815 "inform7/Chapter 5/Preform.w"
;
Text__Languages__log_production(pr, FALSE); LOG("\n");
}
#ifdef INSTRUMENTED_PREFORM
pr->production_tries++;
#endif
int slow_scan_needed = FALSE;
if ((input_length >= pr->min_pr_words) && (input_length <= pr->max_pr_words)) {
int Q; void *QP = NULL;
{
#line 1876 "inform7/Chapter 5/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 1920 "inform7/Chapter 5/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 = w1+p-1;
else if (p < 0) wn = w2+p+1;
if (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 != w2)) goto Fail; /* input text goes on further */
}
#line 1881 "inform7/Chapter 5/Preform.w"
;
if (slow_scan_needed)
{
#line 1947 "inform7/Chapter 5/Preform.w"
int spos[MAX_STRUTS_PER_PRODUCTION]; /* word numbers for where we are trying the struts */
int NS = pr->no_struts;
{
#line 1970 "inform7/Chapter 5/Preform.w"
if (NS == 1) {
spos[0] = next_strut_posn_after(w1, w2, pr->struts[0], pr->strut_lengths[0], w1);
if (spos[0] == -1) goto Fail;
} else if (NS > 1) {
int s, from = w1;
for (s=0; s<NS; s++) {
spos[s] = next_strut_posn_after(w1, w2, pr->struts[s], pr->strut_lengths[s], from);
if (spos[s] == -1) goto Fail;
from = spos[s] + pr->strut_lengths[s] + 1;
}
}
}
#line 1949 "inform7/Chapter 5/Preform.w"
;
ptoken *backtrack_token = NULL;
int backtrack_index = -1, backtrack_to = -1, backtrack_tc = -1;
while (TRUE) {
{
#line 2011 "inform7/Chapter 5/Preform.w"
int wn = w1, 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_w1[pt->range_starts] = wn;
switch (pt->ptoken_category) {
case FIXED_WORD_PTC:
{
#line 2043 "inform7/Chapter 5/Preform.w"
int q = 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 2029 "inform7/Chapter 5/Preform.w"
; break;
case SINGLE_WILDCARD_PTC:
{
#line 2052 "inform7/Chapter 5/Preform.w"
wn++;
}
#line 2030 "inform7/Chapter 5/Preform.w"
; break;
case MULTIPLE_WILDCARD_PTC:
{
#line 2057 "inform7/Chapter 5/Preform.w"
if (wn > w2) goto FailThisStrutPosition;
int wt;
{
#line 2140 "inform7/Chapter 5/Preform.w"
ptoken *lookahead = nextpt;
if (lookahead == NULL) wt = w2;
else {
int p = lookahead->ptoken_position;
if (p > 0) wt = w1+p-2;
else if (p < 0) wt = w2+p;
else if (lookahead->strut_number >= 0) wt = spos[lookahead->strut_number]-1;
else if ((lookahead->nt_pt)
&& (pt->negated_ptoken == FALSE)
&& (ptoken_width(pt) == PTOKEN_ELASTIC)) {
int j;
wt = -1;
nonterminal *target = lookahead->nt_pt;
int save_preform_lookahead_mode = preform_lookahead_mode;
preform_lookahead_mode = TRUE;
for (j = wn+1; j <= w2; j++) {
if (parse_nt_against_word_range(target, j, w2, NULL, NULL)) {
if ((pt->nt_pt == NULL) ||
(parse_nt_against_word_range(pt->nt_pt, 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 5/Preform.w"
;
if (wn > wt) goto FailThisStrutPosition; /* zero length */
if (pt->balanced_wildcard) {
int i, bl = 0;
for (i=wn; i<=wt; i++) {
if ((Text__word(i) == OPENBRACKET_V) || (Text__word(i) == OPENBRACE_V)) bl++;
if ((Text__word(i) == CLOSEBRACKET_V) || (Text__word(i) == CLOSEBRACE_V)) {
bl--;
if (bl < 0) goto FailThisStrutPosition;
}
}
if (bl != 0) goto FailThisStrutPosition;
}
wn = wt+1;
}
#line 2031 "inform7/Chapter 5/Preform.w"
; break;
case POSSIBLY_EMPTY_WILDCARD_PTC:
{
#line 2077 "inform7/Chapter 5/Preform.w"
int wt;
{
#line 2140 "inform7/Chapter 5/Preform.w"
ptoken *lookahead = nextpt;
if (lookahead == NULL) wt = w2;
else {
int p = lookahead->ptoken_position;
if (p > 0) wt = w1+p-2;
else if (p < 0) wt = w2+p;
else if (lookahead->strut_number >= 0) wt = spos[lookahead->strut_number]-1;
else if ((lookahead->nt_pt)
&& (pt->negated_ptoken == FALSE)
&& (ptoken_width(pt) == PTOKEN_ELASTIC)) {
int j;
wt = -1;
nonterminal *target = lookahead->nt_pt;
int save_preform_lookahead_mode = preform_lookahead_mode;
preform_lookahead_mode = TRUE;
for (j = wn+1; j <= w2; j++) {
if (parse_nt_against_word_range(target, j, w2, NULL, NULL)) {
if ((pt->nt_pt == NULL) ||
(parse_nt_against_word_range(pt->nt_pt, 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 5/Preform.w"
;
wn = wt+1;
}
#line 2032 "inform7/Chapter 5/Preform.w"
; break;
case NONTERMINAL_PTC:
{
#line 2088 "inform7/Chapter 5/Preform.w"
if ((wn > w2) && (pt->nt_pt->min_nt_words > 0)) goto FailThisStrutPosition;
int wt;
if (pt->nt_pt->voracious) wt = w2;
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 5/Preform.w"
ptoken *lookahead = nextpt;
if (lookahead == NULL) wt = w2;
else {
int p = lookahead->ptoken_position;
if (p > 0) wt = w1+p-2;
else if (p < 0) wt = w2+p;
else if (lookahead->strut_number >= 0) wt = spos[lookahead->strut_number]-1;
else if ((lookahead->nt_pt)
&& (pt->negated_ptoken == FALSE)
&& (ptoken_width(pt) == PTOKEN_ELASTIC)) {
int j;
wt = -1;
nonterminal *target = lookahead->nt_pt;
int save_preform_lookahead_mode = preform_lookahead_mode;
preform_lookahead_mode = TRUE;
for (j = wn+1; j <= w2; j++) {
if (parse_nt_against_word_range(target, j, w2, NULL, NULL)) {
if ((pt->nt_pt == NULL) ||
(parse_nt_against_word_range(pt->nt_pt, 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 5/Preform.w"
;
if (pt == backtrack_token) {
if (ptraci) {
LOG("Reached backtrack position %s: <$W>\n",
Text__Vocabulary__get_exemplar(pt->nt_pt->nonterminal_id, FALSE), wn, wt);
}
preform_backtrack = intermediate_ps[pt->result_index];
}
if (ptraci) LOG_INDENT;
int q = parse_nt_against_word_range(pt->nt_pt, 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",
Text__Vocabulary__get_exemplar(pt->nt_pt->nonterminal_id, FALSE),
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 2033 "inform7/Chapter 5/Preform.w"
; break;
}
if (pt->range_ends >= 0) nt->range_result_w2[pt->range_ends] = wn - 1;
}
}
if (wn != w2+1) goto FailThisStrutPosition;
}
#line 1953 "inform7/Chapter 5/Preform.w"
;
break;
FailThisStrutPosition: ;
if (backtrack_token) continue;
{
#line 1988 "inform7/Chapter 5/Preform.w"
if (NS == 0) goto Fail;
else if (NS == 1) {
spos[0] = next_strut_posn_after(w1, w2, 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 = next_strut_posn_after(w1, w2, 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] = next_strut_posn_after(w1, w2, pr->struts[s], pr->strut_lengths[s], from);
if (spos[s] == -1) goto Fail;
from = spos[s] + pr->strut_lengths[s] + 1;
}
}
}
#line 1957 "inform7/Chapter 5/Preform.w"
;
}
}
#line 1882 "inform7/Chapter 5/Preform.w"
;
if ((parsed_open_pos >= 0) && (parsed_close_pos >= 0))
if (Text__paired_brackets(parsed_open_pos, parsed_close_pos) == FALSE)
goto Fail;
{
#line 1904 "inform7/Chapter 5/Preform.w"
if (nt->result_compositor) {
intermediates[0] = pr->match_number;
int f = (*(nt->result_compositor))(&Q, &QP, intermediates, intermediate_ps, w1, w2);
if (f == FALSE) goto Fail;
if ((f >= FAIL_NONTERMINAL) && (f < FAIL_NONTERMINAL_TO)) {
fail_nonterminal_quantum = f - FAIL_NONTERMINAL;
{
#line 1722 "inform7/Chapter 5/Preform.w"
if (ptraci) LOG("Failed\n");
ptraci = teppic;
return FALSE;
}
#line 1910 "inform7/Chapter 5/Preform.w"
;
}
} else {
Q = pr->match_number; QP = NULL;
}
}
#line 1887 "inform7/Chapter 5/Preform.w"
;
}
#line 1825 "inform7/Chapter 5/Preform.w"
;
#ifdef INSTRUMENTED_PREFORM /* record the sentence containing the longest example */
pr->production_matches++;
if ((current_sentence) &&
(w1 >= current_sentence->word_ref1) && (w2 <= current_sentence->word_ref2) &&
((pr->sample_sentence == NULL) || (pr->sample_w2 - pr->sample_w1 < w2 - w1))) {
pr->sample_sentence = current_sentence;
pr->sample_w1 = w1; pr->sample_w2 = w2;
} else if (pr->sample_w1 < 0) {
pr->sample_w1 = w1; pr->sample_w2 = w2;
}
#endif
if (ptraci) {
{
#line 1857 "inform7/Chapter 5/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 1840 "inform7/Chapter 5/Preform.w"
;
LOG("succeeded (%s): ", (slow_scan_needed)?"slowly":"quickly");
LOG("result: %d\n", Q); LOG_OUTDENT;
}
{
#line 1730 "inform7/Chapter 5/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 1844 "inform7/Chapter 5/Preform.w"
;
}
Fail:
if (ptraci) {
{
#line 1857 "inform7/Chapter 5/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 1849 "inform7/Chapter 5/Preform.w"
;
LOG("failed (%s)\n", (slow_scan_needed)?"slowly":"quickly");
LOG_OUTDENT;
}
}
#line 1784 "inform7/Chapter 5/Preform.w"
;
} else {
if (ptraci) {
LOG("production in %s: ",
Text__Vocabulary__get_exemplar(nt->nonterminal_id, FALSE));
Text__Languages__log_production(pr, FALSE);
LOG(": <$W> violates ", w1, w2);
log_range_requirement(&(pr->production_req));
LOG("\n");
}
}
}
}
}
} else {
if (ptraci) {
LOG("%s: <$W> violates ",
Text__Vocabulary__get_exemplar(nt->nonterminal_id, FALSE),
w1, w2);
log_range_requirement(&(nt->nonterminal_req));
LOG("\n");
}
}
}
}
#line 1713 "inform7/Chapter 5/Preform.w"
;
}
{
#line 1722 "inform7/Chapter 5/Preform.w"
if (ptraci) LOG("Failed\n");
ptraci = teppic;
return FALSE;
}
#line 1716 "inform7/Chapter 5/Preform.w"
;
}
#line 2181 "inform7/Chapter 5/Preform.w"
int next_strut_posn_after(int w1, int w2, ptoken *start, int len, int from) {
int last_legal_position = w2-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 (parse_fixed_word_ptoken(pos, pt)) pos++;
else break;
} else {
int q = parse_nt_against_word_range(pt->nt_pt, 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 5/Preform.w"
int parse_fixed_word_ptoken(int wn, ptoken *pt) {
vocabulary_entry *ve = Text__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 84 "inform7/Chapter 5/Non-Parsing Preform.w"
word_assemblage Text__Languages__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 = Text__Words__lit_0();
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
if (pt->ptoken_category == FIXED_WORD_PTC) {
wa = Text__Words__join(wa, Text__Words__lit_1(pt->ve_pt));
} else if (pt->ptoken_category == MULTIPLE_WILDCARD_PTC) {
wa = Text__Words__join(wa, ingredient);
}
}
return wa;
}
N++;
}
}
return Text__Words__lit_0(); /* give up, in other words */
}
#line 112 "inform7/Chapter 5/Non-Parsing Preform.w"
word_assemblage Text__Languages__wording(nonterminal *nt, int pnum) {
return Text__Languages__merge(nt, pnum, Text__Words__lit_0());
}
#line 119 "inform7/Chapter 5/Non-Parsing Preform.w"
vocabulary_entry *Text__Languages__word(nonterminal *nt, int pnum) {
word_assemblage wa = Text__Languages__merge(nt, pnum, Text__Words__lit_0());
vocabulary_entry **words;
int num_words;
Text__Words__as_array(&wa, &words, &num_words);
if (num_words == 1) return words[0];
return NULL;
}
#line 133 "inform7/Chapter 5/Non-Parsing Preform.w"
vocabulary_entry *Text__Languages__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 167 "inform7/Chapter 5/Non-Parsing Preform.w"
void Text__Languages__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(-1, -1, pos,
Text__Words__lit_1(ve), category, gloss);
}
}
}
}
}
}
#line 195 "inform7/Chapter 5/Non-Parsing Preform.w"
match_avinue *Text__Languages__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 215 "inform7/Chapter 5/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)) {
Text__Languages__log_production(pr, FALSE);
trie_definition_error(nt, pr, "trie line with more than 2 words");
}
{
#line 242 "inform7/Chapter 5/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 272 "inform7/Chapter 5/Non-Parsing Preform.w"
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 257 "inform7/Chapter 5/Non-Parsing Preform.w"
;
{
#line 279 "inform7/Chapter 5/Non-Parsing Preform.w"
match_avinue *next_mt =
Text__Inflections__fresh_avinue(Text__Languages__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 258 "inform7/Chapter 5/Non-Parsing Preform.w"
;
list_grammar = TRUE;
} else {
if (list_grammar == TRUE)
{
#line 272 "inform7/Chapter 5/Non-Parsing Preform.w"
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 261 "inform7/Chapter 5/Non-Parsing Preform.w"
;
if (second == NULL)
trie_definition_error(nt, pr,
"there should be two words here, a pattern and an instruction");
{
#line 291 "inform7/Chapter 5/Non-Parsing Preform.w"
if (ave == NULL) ave = Text__Inflections__new_avinue(end);
Text__Inflections__add_to_avinue(ave,
Text__Vocabulary__get_exemplar(first->ve_pt, FALSE),
Text__Vocabulary__get_exemplar(second->ve_pt, FALSE));
}
#line 265 "inform7/Chapter 5/Non-Parsing Preform.w"
;
list_grammar = FALSE;
}
}
#line 225 "inform7/Chapter 5/Non-Parsing Preform.w"
;
}
}
#line 202 "inform7/Chapter 5/Non-Parsing Preform.w"
;
pl->as_avinue = ave;
}
}
return ave;
}
#line 299 "inform7/Chapter 5/Non-Parsing Preform.w"
void 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",
Text__Vocabulary__get_exemplar(nt->nonterminal_id, FALSE),
pl->definition_language);
Text__Inflections__log_avinue(pl->as_avinue);
}
}
}
}
#line 328 "inform7/Chapter 5/Non-Parsing Preform.w"
verb_conjugation *Text__Languages__conjugate_verb(word_assemblage base_text,
word_assemblage *overrides, int no_overrides, natural_language *nl) {
if (nl == NULL) nl = English_language;
if (Text__Words__nonempty(base_text) == FALSE)
internal_error("No base text for verb conjugation");
word_assemblage verb_forms[MAX_FORM_TYPES+1];
{
#line 349 "inform7/Chapter 5/Non-Parsing Preform.w"
int k;
for (k=0; k<=MAX_FORM_TYPES; k++) verb_forms[k] = base_text;
}
#line 336 "inform7/Chapter 5/Non-Parsing Preform.w"
;
int n = 1, aux_len = 0, avo_flag = FALSE, niv_flag = FALSE;
nonterminal *tabulation =
follow_conjugation_instructions(verb_forms, &n, &aux_len, &avo_flag, &niv_flag, nl);
{
#line 366 "inform7/Chapter 5/Non-Parsing Preform.w"
int k;
for (k=1; k<no_overrides; k++)
if (Text__Words__nonempty(overrides[k]))
verb_forms[k] = overrides[k];
}
#line 342 "inform7/Chapter 5/Non-Parsing Preform.w"
;
{
#line 374 "inform7/Chapter 5/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;
{
#line 394 "inform7/Chapter 5/Non-Parsing Preform.w"
vc->active_tabulation.to_be_auxiliary = Text__Words__lit_0();
vc->passive_tabulation.to_be_auxiliary = Text__Words__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] = Text__Words__lit_0();
vc->passive_tabulation.vc_text[tense][sense][i] = Text__Words__lit_0();
}
}
#line 383 "inform7/Chapter 5/Non-Parsing Preform.w"
;
{
#line 414 "inform7/Chapter 5/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 5/Non-Parsing Preform.w"
int active_set = NOT_APPLICABLE, tense_set = -1, sense_set = -1, set_tba = FALSE;
{
#line 460 "inform7/Chapter 5/Non-Parsing Preform.w"
vocabulary_entry *ve = selector->ve_pt;
char *p = Text__Vocabulary__get_exemplar(ve, FALSE);
if (p[0] == 'a') active_set = TRUE;
if (p[0] == 'p') active_set = FALSE;
if (active_set == NOT_APPLICABLE)
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);
conjugation_error(base_text, tabulation, pr,
"unrecognised selector in tabulation row");
}
}
#line 433 "inform7/Chapter 5/Non-Parsing Preform.w"
;
if (set_tba)
vc->passive_tabulation.to_be_auxiliary =
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] =
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] =
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 5/Non-Parsing Preform.w"
;
} else conjugation_error(base_text, tabulation, pr,
"tabulation row doesn't consist of a selector and then text");
}
}
}
}
#line 384 "inform7/Chapter 5/Non-Parsing Preform.w"
;
if (tabulation == to_be_tabulation_NTM) to_be_conjugation = vc;
/* write_conjugation(dl, vc); */
return vc;
}
#line 343 "inform7/Chapter 5/Non-Parsing Preform.w"
;
}
#line 494 "inform7/Chapter 5/Non-Parsing Preform.w"
nonterminal *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 5/Non-Parsing Preform.w"
vocabulary_entry **base_text_words;
int base_text_word_count;
Text__Words__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 5/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 5/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) &&
(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 5/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)
Text__Words__truncate(&(verb_forms[ADJOINT_INFINITIVE_FORM_TYPE]), wildcard_from);
*aux_len = wildcard_from;
}
}
} else malformed = TRUE;
if (malformed)
conjugation_error(verb_forms[BASE_FORM_TYPE], verb_conjugation_instructions_NTM, pr,
"malformed line");
}
#line 523 "inform7/Chapter 5/Non-Parsing Preform.w"
;
}
}
}
}
#line 500 "inform7/Chapter 5/Non-Parsing Preform.w"
;
if (conjugation_nt == NULL)
conjugation_error(verb_forms[0], instructions_nt, NULL,
"the instructions here failed to choose a conjugation");
{
#line 591 "inform7/Chapter 5/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 5/Non-Parsing Preform.w"
ptoken *number_token = pr->first_ptoken;
ptoken *content_token = number_token->next_ptoken;
int n = 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] =
Text__Inflections__apply_trie_to_wa(
verb_forms[BASE_FORM_TYPE],
Text__Languages__define_trie(content_token->nt_pt, TRIE_END, nl));
else if (content_token->ptoken_category == FIXED_WORD_PTC)
verb_forms[n] =
expand_wa_with_endings(content_token->ve_pt, verb_forms);
else malformed = TRUE;
} else malformed = TRUE;
}
#line 611 "inform7/Chapter 5/Non-Parsing Preform.w"
;
break;
default: malformed = TRUE; break;
}
if (malformed)
conjugation_error(verb_forms[BASE_FORM_TYPE], conjugation_nt, pr,
"malformed line");
}
}
}
}
#line 504 "inform7/Chapter 5/Non-Parsing Preform.w"
;
if (tabulation_nt == NULL)
conjugation_error(verb_forms[0], conjugation_nt, NULL,
"the conjugation here failed to choose a tabulation");
return tabulation_nt;
}
#line 669 "inform7/Chapter 5/Non-Parsing Preform.w"
word_assemblage 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 = Text__Words__lit_0();
int verb_form_to_lift = -1;
ptoken *chunk;
for (chunk = row; chunk; chunk = chunk->next_ptoken) {
{
#line 786 "inform7/Chapter 5/Non-Parsing Preform.w"
if (chunk->ptoken_category == FIXED_WORD_PTC) {
char *p = Text__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 5/Non-Parsing Preform.w"
;
{
#line 731 "inform7/Chapter 5/Non-Parsing Preform.w"
int X = ptoken_to_verb_form_number(chunk);
if ((X >= 0) && (ptoken_as_bracket(chunk->next_ptoken))) {
verb_form_to_lift = X;
continue;
}
}
#line 678 "inform7/Chapter 5/Non-Parsing Preform.w"
;
{
#line 752 "inform7/Chapter 5/Non-Parsing Preform.w"
if (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 = 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 = Text__Words__lit_0();
while ((chunk) && (ptoken_as_bracket(chunk) != -1)) {
verb_lifted = Text__Words__join(verb_lifted,
expand_wa_with_endings(chunk->ve_pt, ingredients));
chunk = chunk->next_ptoken;
}
verb_conjugation *aux = Semantics__find_vc_by_infinitive(verb_lifted);
if (aux == NULL) aux = Text__Languages__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 = Text__Words__join(wa, aux->infinitive); break;
case 2: wa = Text__Words__join(wa, aux->present_participle); break;
case 3: wa = Text__Words__join(wa, aux->past_participle); break;
case -1: wa = Text__Words__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 5/Non-Parsing Preform.w"
;
{
#line 692 "inform7/Chapter 5/Non-Parsing Preform.w"
if (chunk->ptoken_category == FIXED_WORD_PTC) {
wa = Text__Words__join(wa, expand_wa_with_endings(chunk->ve_pt, ingredients));
continue;
}
}
#line 680 "inform7/Chapter 5/Non-Parsing Preform.w"
;
{
#line 705 "inform7/Chapter 5/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 = Text__Words__join(wa,
merge_verb_material(pr->first_ptoken,
sense, tense, person, num_ingredients, ingredients, nl, NULL));
N++;
}
}
continue;
}
}
#line 681 "inform7/Chapter 5/Non-Parsing Preform.w"
;
internal_error("Error in merge material line");
}
return shorten_wa_with_contractions(wa);
}
#line 803 "inform7/Chapter 5/Non-Parsing Preform.w"
word_assemblage expand_wa_with_endings(vocabulary_entry *ve, word_assemblage *verb_forms) {
if (ve == NULL) return Text__Words__lit_0();
char *p = Text__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 =
Text__Vocabulary__entry_for_partial_text(p, 0, i-1);
vocabulary_entry *back =
Text__Vocabulary__entry_for_partial_text(p, i+1, Platform__strlen(p)-1);
word_assemblage front_wa = expand_wa_with_endings(front, verb_forms);
word_assemblage back_wa = expand_wa_with_endings(back, verb_forms);
TEMPORARY_STREAM;
Text__Words__copy_to_stream(TEMP, &front_wa);
if (p[i] == '~') STREAM_PUT(TEMP, ' ');
Text__Words__copy_to_stream(TEMP, &back_wa);
int w1 = lexer_wordcount;
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
int w2 = lexer_wordcount-1;
CLOSE_TEMPORARY_STREAM;
return Text__Words__from_range(w1, w2);
}
int X = ve_to_verb_form_number(ve);
if (X >= 0) return verb_forms[X];
return Text__Words__lit_1(ve);
}
#line 856 "inform7/Chapter 5/Non-Parsing Preform.w"
word_assemblage shorten_wa_with_contractions(word_assemblage wa) {
vocabulary_entry **words;
int word_count;
Text__Words__as_array(&wa, &words, &word_count);
int i;
for (i=0; i<word_count-1; i++) {
char *p = Text__Vocabulary__get_exemplar(words[i], TRUE);
char *q = Text__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 898 "inform7/Chapter 5/Non-Parsing Preform.w"
int incipit = ((unsigned char) q[0]);
int first = tolower(Formats__HTML__without_accent(incipit));
if ((first == 'a') || (first == 'e') || (first == 'i') ||
(first == 'o') || (first == 'u') || (first == 'y'))
contract_this = TRUE;
}
#line 868 "inform7/Chapter 5/Non-Parsing Preform.w"
;
if (contract_this) {
int k;
for (k=0; k<j-1; k++) { STREAM_WRITE(TEMP, "%c", p[k]); }
STREAM_WRITE(TEMP, "'%s", q);
int wn = lexer_wordcount;
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
words[i] = Text__word(wn);
for (k=i+1; k<word_count; k++) words[k] = words[k+1];
word_count--;
Text__Words__truncate_to(&wa, word_count);
} else {
int k;
for (k=0; k<j; k++) { STREAM_WRITE(TEMP, "%c", p[k]); }
int wn = lexer_wordcount;
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
words[i] = Text__word(wn);
}
CLOSE_TEMPORARY_STREAM;
}
}
return wa;
}
#line 908 "inform7/Chapter 5/Non-Parsing Preform.w"
int ptoken_to_verb_form_number(ptoken *pt) {
if ((pt) && (pt->ptoken_category == FIXED_WORD_PTC))
return ve_to_verb_form_number(pt->ve_pt);
return -1;
}
int ve_to_verb_form_number(vocabulary_entry *ve) {
if (Text__Vocabulary__test_vflags(ve, NUMBER_MC)) {
int X = Text__Vocabulary__get_literal_number_value(ve);
if ((X >= 0) && (X < MAX_FORM_TYPES)) return X;
}
return -1;
}
#line 926 "inform7/Chapter 5/Non-Parsing Preform.w"
int 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 = Text__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 953 "inform7/Chapter 5/Non-Parsing Preform.w"
int 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 966 "inform7/Chapter 5/Non-Parsing Preform.w"
int compare_ve_with_tails(vocabulary_entry *ve, vocabulary_entry *pattern) {
if (ve == pattern) return TRUE;
char *p = Text__Vocabulary__get_exemplar(pattern, FALSE);
if (p[0] == '-') {
char *q = Text__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 987 "inform7/Chapter 5/Non-Parsing Preform.w"
void trie_definition_error(nonterminal *nt, production *pr, char *message) {
general_npp_error(Text__Words__lit_0(), nt, pr, message);
}
#line 994 "inform7/Chapter 5/Non-Parsing Preform.w"
void conjugation_error(word_assemblage base_text, nonterminal *nt,
production *pr, char *message) {
general_npp_error(base_text, nt, pr, message);
exit(1);
}
#line 1003 "inform7/Chapter 5/Non-Parsing Preform.w"
void general_npp_error(word_assemblage base_text, nonterminal *nt,
production *pr, char *message) {
if (pr) {
LOG("The production at fault is:\n");
Text__Languages__log_production(pr, FALSE); LOG("\n");
}
if (nt == NULL)
Problems__quote_text(1, "(no nonterminal)");
else
Problems__quote_text(1, Text__Vocabulary__get_exemplar(nt->nonterminal_id, FALSE));
Problems__quote_text(2, message);
Problems__handmade_problem(_P_(Untestable));
if (Text__Words__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) {
Text__Languages__write_ptoken(TEMP, pt);
if (pt->next_ptoken) STREAM_WRITE(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 1051 "inform7/Chapter 5/Non-Parsing Preform.w"
void Semantics__test_conjugation(OUTPUT_STREAM, int w1, int w2) {
verb_conjugation *vc = Text__Languages__conjugate_verb(
Text__Words__from_range(w1, w2), NULL, 0, language_of_play);
if (vc == NULL) { WRITE("Failed test\n"); return; }
write_conjugation(OUT, vc);
DESTROY(vc, verb_conjugation);
}
void write_conjugation(OUTPUT_STREAM, verb_conjugation *vc) {
WRITE("Infinitive: ");
Text__Words__copy_to_stream(OUT, &(vc->infinitive));
WRITE(" / Present participle: ");
Text__Words__copy_to_stream(OUT, &(vc->present_participle));
WRITE(" / Past participle: ");
Text__Words__copy_to_stream(OUT, &(vc->past_participle));
WRITE("^");
int mood_count = 2;
if (Text__Words__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 (Text__Words__nonempty(*wa)) {
Text__Words__copy_to_stream(OUT, wa);
} else {
WRITE("--");
}
}
WRITE("^");
}
}
}
if (Text__Words__nonempty(vc->passive_tabulation.to_be_auxiliary)) {
WRITE("Form passive as to be + ");
Text__Words__copy_to_stream(OUT, &(vc->passive_tabulation.to_be_auxiliary));
WRITE("\n");
}
}
#line 1102 "inform7/Chapter 5/Non-Parsing Preform.w"
void Semantics__test_participle(OUTPUT_STREAM, int w1, int w2) {
verb_conjugation *vc = Text__Languages__conjugate_verb(
Text__Words__from_range(w1, w2), NULL, 0, English_language);
if (vc == NULL) { WRITE("Failed test\n"); return; }
write_participle(OUT, vc);
DESTROY(vc, verb_conjugation);
}
void write_participle(OUTPUT_STREAM, verb_conjugation *vc) {
WRITE("To ");
Text__Words__copy_to_stream(OUT, &(vc->infinitive));
WRITE(": he is ");
Text__Words__copy_to_stream(OUT, &(vc->present_participle));
WRITE(".\n");
}
#line 221 "inform7/Chapter 6/Parse Tree.w"
parse_node *Parser__Nodes__new(int type) {
parse_node *PN = CREATE(parse_node);
PN->node_type = type;
PN->word_ref1 = -1; PN->word_ref2 = -1;
PN->down = NULL; PN->next = NULL;
PN->annotations = NULL;
return PN;
}
#line 234 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__type(parse_node *pn) { return pn->node_type; }
void Parser__Nodes__set_node_type(parse_node *pn, int nt) { pn->node_type = nt; }
#line 242 "inform7/Chapter 6/Parse Tree.w"
parse_node_annotation *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 258 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__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 272 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__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 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 295 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__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 = pna_new(koa); newpna->annotation_integer = v;
if (final) final->next_annotation = newpna; else PN->annotations = newpna;
}
#line 314 "inform7/Chapter 6/Parse Tree.w"
void 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 = pna_new(koa); newpna->annotation_pointer = data;
if (final) final->next_annotation = newpna; else PN->annotations = newpna;
}
#line 352 "inform7/Chapter 6/Parse Tree.w"
MAKE_ANNOTATION_FUNCTIONS(aph, adjectival_phrase)
MAKE_ANNOTATION_FUNCTIONS(creation_proposition, pcalc_prop)
MAKE_ANNOTATION_FUNCTIONS(evaluation, specification)
MAKE_ANNOTATION_FUNCTIONS(grammar_token_relation, binary_predicate)
MAKE_ANNOTATION_FUNCTIONS(grammar_value, specification)
MAKE_ANNOTATION_FUNCTIONS(embodying_heading, heading)
MAKE_ANNOTATION_FUNCTIONS(implicit_in_creation_of, inference_subject)
MAKE_ANNOTATION_FUNCTIONS(interpretation_of_subject, inference_subject)
MAKE_ANNOTATION_FUNCTIONS(relationship, binary_predicate)
MAKE_ANNOTATION_FUNCTIONS(rulebook_basis, kind)
MAKE_ANNOTATION_FUNCTIONS(stored_as_kind, kind)
MAKE_ANNOTATION_FUNCTIONS(subject, inference_subject)
MAKE_ANNOTATION_FUNCTIONS(new_relation_here, binary_predicate)
MAKE_ANNOTATION_FUNCTIONS(action_meaning, action_pattern)
MAKE_ANNOTATION_FUNCTIONS(defn_language, natural_language)
#line 377 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__copy(parse_node *to, parse_node *from) {
parse_node_annotation *pna, *latest = NULL;
*to = *from;
to->annotations = NULL;
for (pna=from->annotations; pna; pna=pna->next_annotation) {
parse_node_annotation *pna_copy = CREATE(parse_node_annotation);
*pna_copy = *pna; pna_copy->next_annotation = NULL;
if (to->annotations == NULL) to->annotations = pna_copy;
else latest->next_annotation = pna_copy;
latest = pna_copy;
}
}
#line 393 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__deep_copy_tree(parse_node *from, parse_node *to, int level) {
if ((from == NULL) || (to == NULL)) internal_error("Null deep copy");
Parser__Nodes__copy(to, from);
if (from->down) {
to->down = Parser__Nodes__new(PROPER_NOUN_NT);
Parser__Nodes__deep_copy_tree(from->down, to->down, level+1);
}
if ((level>0) && (from->next)) {
to->next = Parser__Nodes__new(PROPER_NOUN_NT);
Parser__Nodes__deep_copy_tree(from->next, to->next, level);
}
}
#line 415 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__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 (Parser__Nodes__contains(to_try, to_find))
return TRUE;
return FALSE;
}
#line 436 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__left_edge_of(parse_node *PN) {
parse_node *child;
int l = PN->word_ref1, lc;
for (child = PN->down; child; child = child->next) {
lc = Parser__Nodes__left_edge_of(child);
if ((lc >= 0) && ((l == -1) || (lc < l))) l = lc;
}
return l;
}
#line 450 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__right_edge_of(parse_node *PN) {
parse_node *child;
int r = PN->word_ref2, rc;
if (PN->word_ref1 < 0) r = -1;
for (child = PN->down; child; child = child->next) {
rc = Parser__Nodes__right_edge_of(child);
if ((rc >= 0) && ((r == -1) || (rc > r))) r = rc;
}
return r;
}
#line 466 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__plant_parse_tree(void) {
tree_root = Parser__Nodes__new(ROOT_NT);
}
#line 483 "inform7/Chapter 6/Parse Tree.w"
parse_node *youngest_child_of_root = NULL; /* youngest child of tree root */
int allow_last_sentence_cacheing = FALSE;
void Parser__Nodes__enable_last_sentence_cacheing(void) {
youngest_child_of_root = NULL; /* because this may have changed since last enabled */
allow_last_sentence_cacheing = TRUE;
}
void Parser__Nodes__disable_last_sentence_cacheing(void) {
allow_last_sentence_cacheing = FALSE;
}
#line 509 "inform7/Chapter 6/Parse Tree.w"
parse_node *Parser__Nodes__graft(parse_node *newborn, parse_node *parent) {
parse_node *elder = NULL;
if (newborn == NULL) internal_error("newborn is null in tree Parser__Nodes__graft");
if (parent == NULL) internal_error("parent is null in tree Parser__Nodes__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 535 "inform7/Chapter 6/Parse Tree.w"
int Parser__Nodes__is_adjlist(parse_node *p) {
if (p == NULL) return FALSE;
switch (Parser__Nodes__type(p)) {
case ADJECTIVE_NT: return TRUE;
case AND_NT: return ((Parser__Nodes__is_adjlist(p->down)) && (Parser__Nodes__is_adjlist(p->down->next)));
default: return FALSE;
}
}
#line 551 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__log(parse_node *p) {
log_single_node(p, 1);
}
void Parser__Nodes__log_subtree_at_current_margin(parse_node *p) {
Parser__Nodes__log_subtree(p, 1);
}
#line 564 "inform7/Chapter 6/Parse Tree.w"
void Parser__Nodes__log_subtree(parse_node *p, int indentation) {
if (p == NULL) { LOG("<null-parse-node>"); return; }
log_single_node(p, indentation);
if (p->down) { log_subtree_recursively(p->down, indentation+1); }
}
void log_subtree_recursively(parse_node *p, int indentation) {
if (p == NULL) { LOG("<null-parse-node>"); return; }
log_single_node(p, indentation);
if (p->down) { log_subtree_recursively(p->down, indentation+1); }
if (p->next) { log_subtree_recursively(p->next, indentation); }
}
#line 582 "inform7/Chapter 6/Parse Tree.w"
void log_single_node(parse_node *p, int indentation) {
int t;
while (indentation-- > 0) LOG(" ");
if (p == NULL) { LOG("<null-parse-node>"); return; }
t = p->node_type;
if ((t<1) || (t>HIGHEST_NODE_TYPE)) { LOG("<node with bad type %d>\n", t); return; }
LOG("node:$N ", t);
if (p->word_ref1 >= 0) {
int w1 = p->word_ref1, w2 = p->word_ref2;
if (w2 < 0) w2 = w1;
LOG(" <$W>", w1, w2);
}
{
#line 604 "inform7/Chapter 6/Parse Tree.w"
int show_eval = FALSE, show_refers = FALSE;
switch(t) {
case ADJECTIVE_NT: show_eval = TRUE; break;
case HEADING_NT: LOG(" (level %d)", Parser__Nodes__int_annotation(p, heading_level_ANNOT)); break;
case COMMON_NOUN_NT: show_refers = TRUE; break;
case KIND_NT: show_refers = TRUE; break;
case RELATIONSHIP_NT: LOG(" (type:");
switch (Parser__Nodes__int_annotation(p, 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 (Parser__Nodes__int_annotation(p, 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 (Parser__Nodes__int_annotation(p, plural_reference_ANNOT)) LOG(" (plural)");
if (Parser__Nodes__int_annotation(p, multiplicity_ANNOT))
LOG(" (x%d)", Parser__Nodes__int_annotation(p, multiplicity_ANNOT));
show_refers = TRUE;
break;
case VERB_NT: LOG(" ($V)", Parser__Nodes__int_annotation(p, verb_id_ANNOT)); break;
case TOKEN_NT: LOG(" [%d/%d]", Parser__Nodes__int_annotation(p, slash_class_ANNOT),
Parser__Nodes__int_annotation(p, slash_dash_dash_ANNOT)); break;
}
if (show_refers) {
if (Parser__Nodes__get_subject(p)) { LOG(" refers:$j", Parser__Nodes__get_subject(p)); }
if (Parser__Nodes__get_evaluation(p)) { LOG(" eval:$S", Parser__Nodes__get_evaluation(p)); }
if (Parser__Nodes__int_annotation(p, implicitly_refers_to_ANNOT)) LOG(" (implicit)");
}
if ((show_eval) && (Parser__Nodes__get_evaluation(p))) {
LOG(" eval:$S", Parser__Nodes__get_evaluation(p));
}
if (Parser__Nodes__get_defn_language(p))
LOG(" language:$J", Parser__Nodes__get_defn_language(p));
if (Parser__Nodes__get_creation_proposition(p))
LOG(" (subject to $D)", Parser__Nodes__get_creation_proposition(p));
}
#line 597 "inform7/Chapter 6/Parse Tree.w"
;
LOG("\n");
}
#line 33 "inform7/Chapter 6/Sentences.w"
void Parser__Sentences__declare_source_loaded(void) {
text_loaded_from_source = TRUE;
}
#line 45 "inform7/Chapter 6/Sentences.w"
void Parser__Sentences__break_source(void) {
Parser__Sentences__break(language_definition_top+1, lexer_wordcount-1, NULL, NULL);
Text__Languages__include_required();
}
#line 72 "inform7/Chapter 6/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 85 "inform7/Chapter 6/Sentences.w"
void Parser__Sentences__break(int w1, int w2, extension_file *from_extension,
parse_node *insertion_point) {
int position, sentence_start = w1;
Parser__Nodes__enable_last_sentence_cacheing();
{
#line 129 "inform7/Chapter 6/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 90 "inform7/Chapter 6/Sentences.w"
;
{
#line 143 "inform7/Chapter 6/Sentences.w"
if ((parse_nt_against_word_range(structural_sentence_NTM, sentence_start, w2, NULL, NULL)) && (most_recent_result == TABLE_NT))
sfsm_in_table_mode = TRUE;
else
sfsm_in_table_mode = FALSE;
}
#line 91 "inform7/Chapter 6/Sentences.w"
;
for (position=w1; position<=w2; position++)
if (sentence_start < position) {
int no_stop_words, back_up_one_word;
char stop_character;
{
#line 188 "inform7/Chapter 6/Sentences.w"
int at = position;
no_stop_words = 0; stop_character = '?'; back_up_one_word = FALSE;
while (at < w2) {
int stopped = FALSE;
if (Text__word(at) == PARBREAK_V) { stop_character = '|'; stopped = TRUE; }
if (Text__word(at) == FULLSTOP_V) { stop_character = '.'; stopped = TRUE; }
if (Text__word(at) == SEMICOLON_V) { stop_character = ';'; stopped = TRUE; }
{
#line 227 "inform7/Chapter 6/Sentences.w"
if ((Text__word(at) == COLON_V) &&
((isdigit(*(Text__word_raw_text(at-1))) == FALSE) ||
(isdigit(*(Text__word_raw_text(at+1))) == FALSE) ||
(Text__indentation_level(at+1) > 0))) {
stop_character = ':'; stopped = TRUE;
}
}
#line 197 "inform7/Chapter 6/Sentences.w"
;
{
#line 251 "inform7/Chapter 6/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(*(Text__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 198 "inform7/Chapter 6/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 98 "inform7/Chapter 6/Sentences.w"
;
if (no_stop_words > 0) {
Parser__Sentences__make_node(sentence_start, position-1, stop_character, insertion_point);
if (insertion_point) insertion_point = insertion_point->next;
position = position + no_stop_words - 1;
if (back_up_one_word) sentence_start = position;
else sentence_start = position + 1;
{
#line 143 "inform7/Chapter 6/Sentences.w"
if ((parse_nt_against_word_range(structural_sentence_NTM, sentence_start, w2, NULL, NULL)) && (most_recent_result == TABLE_NT))
sfsm_in_table_mode = TRUE;
else
sfsm_in_table_mode = FALSE;
}
#line 106 "inform7/Chapter 6/Sentences.w"
;
}
}
if ((sentence_start < w2) ||
((sentence_start == w2) && (!(Text__word(w2) == PARBREAK_V)))) {
Parser__Sentences__make_node(sentence_start, w2, '.', insertion_point);
if (insertion_point) insertion_point = insertion_point->next;
}
Parser__Nodes__disable_last_sentence_cacheing();
if (from_extension)
{
#line 481 "inform7/Chapter 6/Sentences.w"
switch (sfsm_extension_position) {
case 1: Problems__extension_problem(_P_(C6ExtNoBeginsHere),
sfsm_extension, "has no 'begins here' sentence"); break;
case 2: Problems__extension_problem(_P_(C6ExtNoEndsHere),
sfsm_extension, "has no 'ends here' sentence"); break;
case 3: break;
}
}
#line 119 "inform7/Chapter 6/Sentences.w"
;
{
#line 129 "inform7/Chapter 6/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 120 "inform7/Chapter 6/Sentences.w"
;
}
#line 278 "inform7/Chapter 6/Sentences.w"
void Parser__Sentences__make_node(int w1, int w2, char stop_character,
parse_node *insertion_point) {
int heading_level = 0, begins_or_ends = 0;
parse_node *new;
if ((w1 < options_file_w1) || (w2 > options_file_w2)) no_sentences_read++;
if (w2<w1) internal_error("empty sentence generated");
Text__Vocabulary__identify_word_range(w1, w2); /* a precaution to catch any late unidentified text */
{
#line 313 "inform7/Chapter 6/Sentences.w"
if (Text__file_of_origin(w1) != sfsm_source_file) {
parse_node *implicit_heading = Parser__Nodes__new(HEADING_NT);
implicit_heading->word_ref1 = w1;
implicit_heading->word_ref2 = w2;
insert_sentence_in_parse_tree(implicit_heading, insertion_point);
Parser__Nodes__annotate_int(implicit_heading, sentence_unparsed_ANNOT, FALSE);
Parser__Nodes__annotate_int(implicit_heading, heading_level_ANNOT, 0);
Parser__Sentences__Headings__declare(implicit_heading);
sfsm_skipping_material_at_level = -1;
}
sfsm_source_file = Text__file_of_origin(w1);
}
#line 288 "inform7/Chapter 6/Sentences.w"
;
{
#line 373 "inform7/Chapter 6/Sentences.w"
if (parse_nt_against_word_range(dividing_sentence_NTM, w1, w2, 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__extension_problem(_P_(C6ExtMultipleBeginsHere),
sfsm_extension, "has more than one 'begins here' sentence"); break;
case 3: Problems__extension_problem(_P_(C6ExtBeginsAfterEndsHere),
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__extension_problem(_P_(C6ExtEndsWithoutBegins),
sfsm_extension, "has an 'ends here' with nothing having begun"); break;
case 2: sfsm_extension_position++; break;
case 3: Problems__extension_problem(_P_(C6ExtMultipleEndsHere),
sfsm_extension, "has more than one 'ends here' sentence"); break;
}
begins_or_ends = -1;
}
break;
default:
heading_level = most_recent_result;
break;
}
}
}
#line 289 "inform7/Chapter 6/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 414 "inform7/Chapter 6/Sentences.w"
int k;
for (k=w1+1; k<=w2; k++)
if ((Text__break_before(k) == '\n') || (Text__indentation_level(k) > 0)) {
Problems__quote_source(1, Parser__Sentences__NPs__new_raw(w1, w2));
Problems__quote_source(2, Parser__Sentences__NPs__new_raw(w1, k-1));
Problems__quote_source(3, Parser__Sentences__NPs__new_raw(k, w2));
Problems__handmade_problem(_P_(C6HeadingOverLine));
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 298 "inform7/Chapter 6/Sentences.w"
;
{
#line 440 "inform7/Chapter 6/Sentences.w"
if (Text__break_before(w2+1) != '\n') {
int k;
for (k = w2+1;
(k<=w2+8) && (k<lexer_wordcount) && (Text__break_before(k) != '\n');
k++) ;
Problems__quote_source(1, Parser__Sentences__NPs__new_raw(w1, w2));
Problems__quote_source(2, Parser__Sentences__NPs__new_raw(w2+1, k-1));
Problems__handmade_problem(_P_(C6HeadingStopsBeforeEndOfLine));
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 299 "inform7/Chapter 6/Sentences.w"
;
{
#line 465 "inform7/Chapter 6/Sentences.w"
heading *h;
new = Parser__Nodes__new(HEADING_NT);
new->word_ref1 = w1;
new->word_ref2 = w2;
insert_sentence_in_parse_tree(new, insertion_point);
Parser__Nodes__annotate_int(new, sentence_unparsed_ANNOT, FALSE);
Parser__Nodes__annotate_int(new, heading_level_ANNOT, heading_level);
h = Parser__Sentences__Headings__declare(new);
Parser__Nodes__set_embodying_heading(new, h);
if (Parser__Sentences__Headings__include_material(h) == FALSE)
sfsm_skipping_material_at_level = heading_level;
}
#line 300 "inform7/Chapter 6/Sentences.w"
;
return;
}
{
#line 328 "inform7/Chapter 6/Sentences.w"
if ((sfsm_extension_position == 3) && (begins_or_ends == 0)) {
LOG("Spurious text: $W\n", w1, w2);
Problems__extension_problem(_P_(C6ExtSpuriouslyContinues),
sfsm_extension, "continues after the 'ends here' sentence");
sfsm_extension_position = 4; /* to avoid multiply issuing this */
}
}
#line 304 "inform7/Chapter 6/Sentences.w"
;
{
#line 550 "inform7/Chapter 6/Sentences.w"
{
#line 629 "inform7/Chapter 6/Sentences.w"
if ((sfsm_inside_rule_mode == FALSE)
&& ((stop_character == '.') || (stop_character == '|'))
&& (parse_nt_against_word_range(comma_divisible_sentence_NTM, w1, w2, NULL, NULL)))
{
#line 639 "inform7/Chapter 6/Sentences.w"
int earliest_comma_position = w1;
{
#line 655 "inform7/Chapter 6/Sentences.w"
if (parse_nt_against_word_range(list_or_division_NTM, w1, w2, NULL, NULL)) {
int b1, b2;
GET_RW(list_or_division_NTM, 2, b1, b2);
earliest_comma_position = b1;
}
}
#line 640 "inform7/Chapter 6/Sentences.w"
;
int a1 = -1, a2 = -1, b1 = -1, b2 = -1;
if (parse_nt_against_word_range(list_comma_division_NTM, earliest_comma_position, w2, NULL, NULL)) {
GET_RW(list_comma_division_NTM, 1, a1, a2);
GET_RW(list_comma_division_NTM, 2, b1, b2);
}
if (a1 >= 0) {
Parser__Sentences__make_node(w1, a2, ':', NULL); /* rule preamble stopped with a colon */
Parser__Sentences__make_node(b1, b2, '.', NULL); /* rule body with one sentence, stopped with a stop */
return;
}
}
#line 632 "inform7/Chapter 6/Sentences.w"
;
}
#line 550 "inform7/Chapter 6/Sentences.w"
;
{
#line 667 "inform7/Chapter 6/Sentences.w"
new = Parser__Nodes__new(SENTENCE_NT);
new->word_ref1 = w1;
new->word_ref2 = w2;
Parser__Nodes__annotate_int(new, sentence_unparsed_ANNOT, FALSE);
insert_sentence_in_parse_tree(new, insertion_point);
}
#line 551 "inform7/Chapter 6/Sentences.w"
;
{
#line 707 "inform7/Chapter 6/Sentences.w"
if (stop_character == ':') {
if ((sfsm_inside_rule_mode) && (Parser__Sentences__detect_control_structure(w1, w2))) {
Parser__Nodes__set_node_type(new, COMMAND_NT);
Parser__Nodes__annotate_int(new, colon_block_command_ANNOT, TRUE);
sfsm_inside_rule_mode = TRUE;
return;
} else {
Parser__Nodes__set_node_type(new, ROUTINE_NT);
sfsm_inside_rule_mode = TRUE;
return;
}
}
}
#line 553 "inform7/Chapter 6/Sentences.w"
;
if (sfsm_inside_rule_mode)
{
#line 724 "inform7/Chapter 6/Sentences.w"
Parser__Nodes__set_node_type(new, COMMAND_NT);
if (stop_character != ';') sfsm_inside_rule_mode = FALSE;
return;
}
#line 555 "inform7/Chapter 6/Sentences.w"
else if (stop_character == ';') {
Problems__quote_source(1, Parser__Sentences__NPs__new_raw(w1, w2));
Problems__handmade_problem(_P_(C6UnexpectedSemicolon));
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 (parse_nt_against_word_range(structural_sentence_NTM, w1, w2, NULL, NULL)) {
if (most_recent_result == -1)
{
#line 752 "inform7/Chapter 6/Sentences.w"
int p1, p2;
GET_RW(language_modifying_sentence_NTM, 1, p1, p2);
current_sentence = new;
Config__Plugins__plug_in(p1, p2);
Parser__Nodes__annotate_int(new, language_element_ANNOT, TRUE);
Parser__Nodes__annotate_int(new, sentence_unparsed_ANNOT, FALSE);
}
#line 571 "inform7/Chapter 6/Sentences.w"
else if (most_recent_result == -2) {
{
#line 762 "inform7/Chapter 6/Sentences.w"
int p1, p2;
GET_RW(language_modifying_sentence_NTM, 1, p1, p2);
current_sentence = new;
Text__Languages__parse_preform(p1, p2, TRUE);
Parser__Nodes__annotate_int(new, sentence_unparsed_ANNOT, FALSE);
}
#line 573 "inform7/Chapter 6/Sentences.w"
Parser__Nodes__set_node_type(new, INFORM6CODE_NT); return;
} else {
if (most_recent_result == INCLUDE_NT) {
new->down = most_recent_result_p;
if (first_extension_inclusion == NULL) first_extension_inclusion = new;
}
Parser__Nodes__set_node_type(new, most_recent_result);
if (most_recent_result == BIBLIOGRAPHIC_NT)
Text__Languages__set_language_of_play(
Plugins__Bibliographic__scan_language(new));
return;
}
}
{
#line 732 "inform7/Chapter 6/Sentences.w"
if (begins_or_ends == 1) {
Parser__Nodes__set_node_type(new, BEGINHERE_NT);
new->word_ref1 = w1;
new->word_ref2 = w2 - 2;
Extensions__Inclusion__check_begins_here(new, sfsm_extension);
return;
}
if (begins_or_ends == -1) {
new->word_ref1 = w1;
new->word_ref2 = w2 - 2;
Parser__Nodes__set_node_type(new, ENDHERE_NT);
Extensions__Inclusion__check_ends_here(new, sfsm_extension);
return;
}
}
#line 588 "inform7/Chapter 6/Sentences.w"
;
/* none of that happened, so we have a SENTENCE node for certain */
if (text_loaded_from_source) Parser__Sentences__VPs__seek(new);
else Parser__Nodes__annotate_int(new, sentence_unparsed_ANNOT, TRUE);
}
#line 305 "inform7/Chapter 6/Sentences.w"
;
}
#line 355 "inform7/Chapter 6/Sentences.w"
int dividing_sentence_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 358 "inform7/Chapter 6/Sentences.w"
int heading_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 365 "inform7/Chapter 6/Sentences.w"
int extension_end_marker_sentence_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 369 "inform7/Chapter 6/Sentences.w"
#line 516 "inform7/Chapter 6/Sentences.w"
int structural_sentence_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = BIBLIOGRAPHIC_NT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 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 = TRACE_NT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = TRACE_NT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = TABLE_NT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = EQUATION_NT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = 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 = 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 526 "inform7/Chapter 6/Sentences.w"
#line 533 "inform7/Chapter 6/Sentences.w"
int language_modifying_sentence_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 536 "inform7/Chapter 6/Sentences.w"
#line 544 "inform7/Chapter 6/Sentences.w"
int use_option_sentence_shape_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 546 "inform7/Chapter 6/Sentences.w"
#line 604 "inform7/Chapter 6/Sentences.w"
int comma_divisible_sentence_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 610 "inform7/Chapter 6/Sentences.w"
#line 622 "inform7/Chapter 6/Sentences.w"
int list_or_division_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 625 "inform7/Chapter 6/Sentences.w"
#line 771 "inform7/Chapter 6/Sentences.w"
void insert_sentence_in_parse_tree(parse_node *new, parse_node *insertion_point) {
if (insertion_point == NULL)
Parser__Nodes__graft(new, tree_root);
else {
parse_node *L = insertion_point->next;
insertion_point->next = new;
new->next = L;
}
}
#line 89 "inform7/Chapter 6/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 6/Virtual Machines.w"
#line 104 "inform7/Chapter 6/Virtual Machines.w"
int target_VM; /* an index in the above table, or -1 if unknown */
void Code__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 6/Virtual Machines.w"
int Code__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 6/Virtual Machines.w"
int Code__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 Code__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 6/Virtual Machines.w"
int Code__VirtualMachines__supports(kind *K) {
if (target_VM == -1) internal_error("target VM not set yet");
if ((Kinds__uses_floating_point(K)) &&
(table_of_VM_data[target_VM].VM_is_32_bit == FALSE)) return FALSE;
return TRUE;
}
#line 161 "inform7/Chapter 6/Virtual Machines.w"
char *Code__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 6/Virtual Machines.w"
char *Code__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 6/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 match_VM_against(int w1, int w2) {
{
#line 207 "inform7/Chapter 6/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 6/Virtual Machines.w"
;
parse_nt_against_word_range(vm_description_list_NTM, w1, w2, NULL, NULL);
}
#line 222 "inform7/Chapter 6/Virtual Machines.w"
int vm_description_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 6/Virtual Machines.w"
int vm_description_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 230 "inform7/Chapter 6/Virtual Machines.w"
int vm_description_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 244 "inform7/Chapter 6/Virtual Machines.w"
{
#line 263 "inform7/Chapter 6/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(w1, table_of_VM_data[i].VM_major_name))) {
most_recent_major_VM = table_of_VM_data[i].VM_code;
version_can_be_inferred = FALSE;
w1++;
break;
}
}
#line 244 "inform7/Chapter 6/Virtual Machines.w"
;
{
#line 280 "inform7/Chapter 6/Virtual Machines.w"
if (most_recent_major_VM == -1) THROW_VM_MATCHING_ERROR_AND_RETURN;
}
#line 245 "inform7/Chapter 6/Virtual Machines.w"
;
if (w1 <= w2) {
int version_specified = -1;
if (parse_nt_against_word_range(version_identification_NTM, w1, w2, NULL, NULL)) {
version_specified = VMULT * most_recent_result;
version_can_be_inferred = TRUE;
} else if ((version_can_be_inferred) && (parse_nt_against_word_range(cardinal_number_NTM, w1, w2, NULL, NULL))) {
version_specified = VMULT * most_recent_result;
} else THROW_VM_MATCHING_ERROR_AND_RETURN;
{
#line 298 "inform7/Chapter 6/Virtual Machines.w"
int i;
for (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 6/Virtual Machines.w"
;
} else {
{
#line 285 "inform7/Chapter 6/Virtual Machines.w"
int i;
for (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 6/Virtual Machines.w"
;
}
}
#line 232 "inform7/Chapter 6/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 6/Virtual Machines.w"
#line 238 "inform7/Chapter 6/Virtual Machines.w"
int version_identification_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 6/Virtual Machines.w"
#line 309 "inform7/Chapter 6/Virtual Machines.w"
int virtual_machine_NTMR(int w1, int w2, int *X, void **XP) {
#line 310 "inform7/Chapter 6/Virtual Machines.w"
if (target_VM == -1) internal_error("target VM not set yet");
match_VM_against(w1, w2);
if (VM_matching_error_thrown) return FALSE;
if (table_of_VM_data[target_VM].VM_matches) *X = TRUE;
else *X = FALSE;
return TRUE;
}
#line 324 "inform7/Chapter 6/Virtual Machines.w"
void plot_VM_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 Code__VirtualMachines__write_key(OUTPUT_STREAM) {
int i;
WRITE("Extensions compatible with specific story file formats only: ");
for (i=0; table_of_VM_data[i].VM_code >= 0; i++) {
if (i>0) WRITE(", ");
plot_VM_icon(OUT, i);
WRITE("%s", table_of_VM_data[i].VM_name);
}
WRITE("<p>");
}
#line 344 "inform7/Chapter 6/Virtual Machines.w"
void Code__VirtualMachines__index_innards(void) {
Code__VirtualMachines__write_current();
Config__Inclusions__UseOptions__index();
INDEX("<p>");
Index__extra_link(3);
INDEX("See some technicalities for Inform maintainers only</p>");
Index__extra_div_open(3, 2, "e0e0e0");
Config__Plugins__show_configuration(ifl);
INDEX("<p>Debugging log:</p><p>");
Log__paste_icons();
Index__extra_div_close("e0e0e0");
}
void Code__VirtualMachines__write_current(void) {
if (target_VM == -1) internal_error("target VM not set yet");
Index__anchor("STORYFILE");
INDEX("<p>Story file format: ");
plot_VM_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 (Code__VirtualMachines__is_16_bit()) {
INDEX("<p>"); Index__extra_link(1); INDEX("See estimates of memory usage</p>");
Index__extra_div_open(1, 1, "e0e0e0");
index_memory_usage();
Index__extra_div_close("e0e0e0");
}
}
#line 378 "inform7/Chapter 6/Virtual Machines.w"
void Code__VirtualMachines__write_icons(OUTPUT_STREAM, int w1, int w2) {
int i;
match_VM_against(w1, w2);
{
#line 393 "inform7/Chapter 6/Virtual Machines.w"
int i, everything_matches = TRUE;
for (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 381 "inform7/Chapter 6/Virtual Machines.w"
;
{
#line 405 "inform7/Chapter 6/Virtual Machines.w"
int i, every_Z_matches = TRUE;
for (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 419 "inform7/Chapter 6/Virtual Machines.w"
int i;
for (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 411 "inform7/Chapter 6/Virtual Machines.w"
;
}
#line 382 "inform7/Chapter 6/Virtual Machines.w"
;
for (i=0; table_of_VM_data[i].VM_code >= 0; i++)
if (table_of_VM_data[i].VM_matches)
plot_VM_icon(OUT, i);
}
#line 435 "inform7/Chapter 6/Virtual Machines.w"
void Code__VirtualMachines__note_usage(char *cat, int w1, int w2, char *name, int words, int bytes, int each) {
int b = bytes + words*((Code__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->word_ref1 = w1; VMun->word_ref2 = w2;
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 453 "inform7/Chapter 6/Virtual Machines.w"
void 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 493 "inform7/Chapter 6/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 *), compare_VM_usage_notes);
}
#line 461 "inform7/Chapter 6/Virtual Machines.w"
;
{
#line 470 "inform7/Chapter 6/Virtual Machines.w"
Formats__HTML__begin_plain_html_table(ifl);
int i;
VM_usage_note *VMun;
for (i=0; i<nr; i++) {
VMun = sorted[i];
Formats__HTML__first_html_column(ifl, 0);
INDEX("%s", VMun->usage_category);
Formats__HTML__next_html_column(ifl, 0);
if (VMun->each_flag) INDEX("each ");
if (VMun->usage_explained[0])
INDEX("%s", VMun->usage_explained);
else if (VMun->word_ref1 >= 0)
Text__print_text_to_stream(VMun->word_ref1, VMun->word_ref2, ifl);
if (VMun->word_ref1 >= 0) Index__link(VMun->word_ref1);
Formats__HTML__next_html_column(ifl, 0);
INDEX("%d bytes", VMun->bytes_used);
Formats__HTML__end_html_row(ifl);
}
Formats__HTML__end_html_table(ifl);
}
#line 462 "inform7/Chapter 6/Virtual Machines.w"
;
Memory__I7_free(sorted, INDEX_SORTING_MREASON);
}
#line 502 "inform7/Chapter 6/Virtual Machines.w"
int compare_VM_usage_notes(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 v1->word_ref1 - v2->word_ref2;
}
#line 522 "inform7/Chapter 6/Virtual Machines.w"
int next_free_resource_ID = 3;
int Code__VirtualMachines__get_next_free_blorb_resource_ID(void) {
return next_free_resource_ID++;
}
#line 195 "inform7/Chapter 6/Headings.w"
int heading_tree_made_at_least_once = FALSE;
#line 206 "inform7/Chapter 6/Headings.w"
int last_indentation_above_level[NO_HEADING_LEVELS], lial_made = FALSE;
extension_identifier *grammar_eid = NULL;
heading *Parser__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_w1 = -1; h-> in_place_of_w2 = -2;
if ((PN == NULL) || (PN->word_ref1 < 0)) internal_error("heading at textless node");
internal_error_if_node_type_wrong(PN, HEADING_NT);
h->sentence_declaring = PN;
h->start_location = Text__word_location(PN->word_ref1);
h->level = Parser__Nodes__int_annotation(PN, heading_level_ANNOT);
if (h->level > 0)
{
#line 261 "inform7/Chapter 6/Headings.w"
int w1, w2;
grammar_eid = &(h->for_use_with);
w1 = PN->word_ref1; w2 = PN->word_ref2;
current_sentence = PN;
while (parse_nt_against_word_range(heading_qualifier_NTM, w1, w2, 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;
GET_RW(extension_qualifier_NTM, 1, (h->in_place_of_w1), (h->in_place_of_w2));
break;
}
GET_RW(heading_qualifier_NTM, 1, w1, w2);
}
}
#line 226 "inform7/Chapter 6/Headings.w"
;
if ((h->level < 0) || (h->level >= NO_HEADING_LEVELS)) internal_error("impossible level");
{
#line 239 "inform7/Chapter 6/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 229 "inform7/Chapter 6/Headings.w"
;
LOGIF(HEADINGS, "Created heading $H\n", h);
if (heading_tree_made_at_least_once) Parser__Sentences__Headings__make_tree();
return h;
}
#line 294 "inform7/Chapter 6/Headings.w"
int heading_qualifier_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 6/Headings.w"
int bracketed_heading_qualifier_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 6/Headings.w"
int platform_qualifier_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 6/Headings.w"
int platform_identifier_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 329 "inform7/Chapter 6/Headings.w"
Problems__sentence_problem(_P_(C6UnknownLanguageElement),
"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 6/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 338 "inform7/Chapter 6/Headings.w"
Problems__sentence_problem(_P_(C6UnknownVirtualMachine),
"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 6/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 6/Headings.w"
int extension_qualifier_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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
default: *X = R[0]; break;
}
return TRUE;
}
#line 322 "inform7/Chapter 6/Headings.w"
int extension_identifier_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 347 "inform7/Chapter 6/Headings.w"
*X = R[0] + 4;
char exft[MAX_FILENAME_LENGTH], exfa[MAX_FILENAME_LENGTH];
int t1, t2, a1, a2;
GET_RW(extension_identifier_NTM, 1, t1, t2);
GET_RW(extension_identifier_NTM, 2, a1, a2);
Text__print_raw_text_to_string_truncated(t1, t2, exft, MAX_FILENAME_LENGTH);
Text__print_raw_text_to_string_truncated(a1, a2, exfa, MAX_FILENAME_LENGTH);
Extensions__IDs__new(grammar_eid, exfa, exft, USEWITH_EIDBC);
}
#line 324 "inform7/Chapter 6/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 325 "inform7/Chapter 6/Headings.w"
#line 364 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__make_tree(void) {
heading *h;
{
#line 382 "inform7/Chapter 6/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 6/Headings.w"
;
LOOP_OVER(h, heading) {
{
#line 396 "inform7/Chapter 6/Headings.w"
if (h->parent_heading == NULL)
make_child_heading(h, &pseudo_heading);
}
#line 369 "inform7/Chapter 6/Headings.w"
;
{
#line 417 "inform7/Chapter 6/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... */
make_child_heading(subseq, h->parent_heading); break; /* ...and becomes h's sibling */
}
make_child_heading(subseq, h); /* all lesser headings in the run become h's children */
}
}
#line 370 "inform7/Chapter 6/Headings.w"
;
}
heading_tree_made_at_least_once = TRUE;
verify_heading_tree();
}
#line 431 "inform7/Chapter 6/Headings.w"
void make_child_heading(heading *ch, heading *pa) {
heading *former_pa = ch->parent_heading;
if (former_pa == pa) return;
{
#line 445 "inform7/Chapter 6/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 6/Headings.w"
;
ch->parent_heading = pa;
{
#line 462 "inform7/Chapter 6/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 6/Headings.w"
;
}
#line 479 "inform7/Chapter 6/Headings.w"
int heading_tree_damaged = FALSE;
void verify_heading_tree(void) {
verify_heading_tree_recursively(&pseudo_heading, -1);
if (heading_tree_damaged) internal_error("heading tree failed to verify");
}
void 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);
}
verify_heading_tree_recursively(h->child_heading, depth+1);
verify_heading_tree_recursively(h->next_heading, depth);
}
#line 503 "inform7/Chapter 6/Headings.w"
int Parser__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 Parser__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 6/Headings.w"
extension_file *Parser__Sentences__Headings__get_extension_containing(heading *h) {
if ((h == NULL) || (h->start_location.file_of_origin == NULL)) return NULL;
return Text__Reader__sf_get_extension_corresponding(h->start_location.file_of_origin);
}
#line 529 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__get_text(heading *h, int *w1, int *w2) {
if ((h == NULL) || (h->level == 0)) { *w1 = -1; *w2 = -1; return; }
*w1 = h->sentence_declaring->word_ref1;
*w2 = h->sentence_declaring->word_ref2;
}
#line 547 "inform7/Chapter 6/Headings.w"
heading *Parser__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 566 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__satisfy_dependencies(void) {
heading *h;
LOOP_OVER(h, heading)
if (h->use_with_or_without != NOT_APPLICABLE)
satisfy_individual_heading_dependency(h);
}
#line 578 "inform7/Chapter 6/Headings.w"
void 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,
Parser__Nodes__int_annotation(h->sentence_declaring,
suppress_heading_dependencies_ANNOT),
h->in_place_of_w1, h->in_place_of_w2, h->use_with_or_without);
if (h->in_place_of_w1 >= 0) {
if (Parser__Nodes__int_annotation(h->sentence_declaring,
suppress_heading_dependencies_ANNOT) == FALSE) {
heading *h2; int found = FALSE;
if (loaded == FALSE)
{
#line 658 "inform7/Chapter 6/Headings.w"
current_sentence = h->sentence_declaring;
Problems__quote_source(1, current_sentence);
Problems__quote_extension_id(2, &(h->for_use_with));
Problems__handmade_problem(_P_(C6HeadingInPlaceOfUnincluded));
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 591 "inform7/Chapter 6/Headings.w"
else {
LOOP_OVER(h2, heading)
if ((h2->sentence_declaring) &&
(Text__compare_perhaps_quoted_word_range(h->in_place_of_w1, h->in_place_of_w2,
h2->sentence_declaring->word_ref1, h2->sentence_declaring->word_ref2)) &&
(Extensions__IDs__match(
Extensions__Files__get_eid(
Parser__Sentences__Headings__get_extension_containing(h2)), eid))) {
found = TRUE;
if (h->level != h2->level)
{
#line 710 "inform7/Chapter 6/Headings.w"
current_sentence = h->sentence_declaring;
Problems__sentence_problem(_P_(C6UnequalHeadingInPlaceOf),
"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 602 "inform7/Chapter 6/Headings.w"
;
excise_material_under(h2, NULL);
excise_material_under(h, h2->sentence_declaring);
break;
}
if (found == FALSE)
{
#line 688 "inform7/Chapter 6/Headings.w"
current_sentence = h->sentence_declaring;
Problems__quote_source(1, current_sentence);
Problems__quote_extension_id(2, &(h->for_use_with));
Problems__quote_words(3, h->in_place_of_w1, h->in_place_of_w2);
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_words(4,
Extensions__Files__get_version_wn(ef), Extensions__Files__get_version_wn(ef));
Problems__handmade_problem(_P_(C6HeadingInPlaceOfUnknown));
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 607 "inform7/Chapter 6/Headings.w"
;
}
}
} else
if (h->use_with_or_without != loaded) excise_material_under(h, NULL);
}
#line 631 "inform7/Chapter 6/Headings.w"
void excise_material_under(heading *h, parse_node *transfer_to) {
LOGIF(HEADINGS, "Excision under $H\n", h);
int lev = h->level;
parse_node *end_of_transfer = NULL;
if (transfer_to) end_of_transfer = transfer_to->next;
if (h->sentence_declaring == NULL) internal_error("stipulations on a non-sentence heading");
parse_node *hpn = h->sentence_declaring;
Parser__Nodes__annotate_int(hpn, suppress_heading_dependencies_ANNOT, TRUE);
parse_node *pn;
for (pn = hpn->next; pn; pn = pn->next) {
if (Parser__Nodes__type(pn) == ENDHERE_NT) break;
if (Parser__Nodes__type(pn) == HEADING_NT) {
if (Parser__Nodes__int_annotation(pn, heading_level_ANNOT) <= lev) break;
heading *h2 = Parser__Nodes__get_embodying_heading(pn);
if ((h->in_place_of_w1 >= 0) && (h2->in_place_of_w1 >= 0))
{
#line 672 "inform7/Chapter 6/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__handmade_problem(_P_(C6HeadingInPlaceOfSubordinate));
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 646 "inform7/Chapter 6/Headings.w"
;
Parser__Nodes__annotate_int(pn, suppress_heading_dependencies_ANNOT, TRUE);
}
if (transfer_to) { transfer_to->next = pn; transfer_to = pn; }
}
hpn->next = pn;
if (transfer_to) transfer_to->next = end_of_transfer;
}
#line 727 "inform7/Chapter 6/Headings.w"
int no_tags_attached = 0;
void Parser__Sentences__Headings__attach_nametag(nametag *new_tag) {
if (current_sentence == NULL) return;
heading *h = Parser__Sentences__Headings__heading_of(Text__word_location(current_sentence->word_ref1));
if (h == NULL) return;
no_tags_attached++;
name_resolution_data *nrd = Data__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 Data__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 749 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__verify_divisions(void) {
nametag *nt; heading *h;
int total = 0, disaster = FALSE;
LOOP_OVER(nt, nametag)
Data__Nametags__name_resolution_data(nt)->heading_count = 0;
LOOP_OVER(h, heading)
LOOP_OVER_NAMETAGS_UNDER(nt, h)
Data__Nametags__name_resolution_data(nt)->heading_count++, total++;
LOOP_OVER(nt, nametag)
if (Data__Nametags__name_resolution_data(nt)->heading_count > 1) {
LOG("$z occurs under %d headings\n",
nt, Data__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 835 "inform7/Chapter 6/Headings.w"
nametag *nt_search_start = NULL, *nt_search_finish = NULL;
#line 844 "inform7/Chapter 6/Headings.w"
heading *nametag_search_list_valid_for_this_heading = NULL; /* initially it's unbuilt */
void Parser__Sentences__Headings__disturb(void) {
nametag_search_list_valid_for_this_heading = NULL;
}
#line 855 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__construct_nametag_search_list(void) {
heading *h = NULL;
{
#line 879 "inform7/Chapter 6/Headings.w"
if ((current_sentence == NULL) || (current_sentence->word_ref1 < 0))
internal_error("cannot establish position P: there is no current sentence");
source_location position_P = Text__word_location(current_sentence->word_ref1);
h = Parser__Sentences__Headings__heading_of(position_P);
}
#line 858 "inform7/Chapter 6/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 889 "inform7/Chapter 6/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 864 "inform7/Chapter 6/Headings.w"
;
int i;
for (i=1; i<=MAX_NAMETAG_PRIORITY; i++)
build_search_list_from(h, NULL, i);
{
#line 898 "inform7/Chapter 6/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);
log_all_headings();
LOG("Making fresh tree:\n");
Parser__Sentences__Headings__make_tree();
log_all_headings();
internal_error_tree_unsafe("reordering of nametags failed");
}
}
#line 870 "inform7/Chapter 6/Headings.w"
;
nametag_search_list_valid_for_this_heading = h;
}
#line 940 "inform7/Chapter 6/Headings.w"
void 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 (Data__Nametags__priority(nt) == p)
{
#line 962 "inform7/Chapter 6/Headings.w"
if (nt_search_finish == NULL) {
nt_search_start = nt;
} else {
if (Data__Nametags__name_resolution_data(nt_search_finish)->next_to_search != NULL)
internal_error("end of tag search list has frayed somehow");
Data__Nametags__name_resolution_data(nt_search_finish)->next_to_search = nt;
}
Data__Nametags__name_resolution_data(nt)->next_to_search = NULL;
nt_search_finish = nt;
}
#line 947 "inform7/Chapter 6/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)
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)
build_search_list_from(within->parent_heading, within, p);
}
#line 977 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__set_nametag_search_score(nametag *nt, int v) {
Data__Nametags__name_resolution_data(nt)->search_score = v;
}
nametag *Parser__Sentences__Headings__highest_scoring_nametag_searched(void) {
nametag *nt, *best_nt = NULL;
int best_score = 0;
LOOP_OVER_NT_SEARCH_LIST(nt) {
int x = Data__Nametags__name_resolution_data(nt)->search_score;
if (x > best_score) { best_nt = nt; best_score = x; }
}
return best_nt;
}
#line 998 "inform7/Chapter 6/Headings.w"
sentence_handler HEADING_SH_handler =
{ HEADING_NT, -1, 0, handle_heading };
void handle_heading(parse_node *PN) {
Parser__Assertions__new_discussion();
}
#line 1010 "inform7/Chapter 6/Headings.w"
void Parser__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("<%s, line %d>",
Text__Reader__sf_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 1024 "inform7/Chapter 6/Headings.w"
void log_all_headings(void) {
heading *h;
LOOP_OVER(h, heading) LOG("$H\n", h);
LOG("\n");
log_headings_recursively(&pseudo_heading, 0);
}
void 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);
log_headings_recursively(h->child_heading, depth+1);
log_headings_recursively(h->next_heading, depth);
}
#line 1044 "inform7/Chapter 6/Headings.w"
int headings_indexed = 0;
void Parser__Sentences__Headings__index(void) {
INDEX("<p><b>");
Plugins__Bibliographic__contents_heading();
INDEX("</b></p><p>CONTENTS</p>");
index_heading_recursively(pseudo_heading.child_heading);
int start_word = FIRST_OBJECT(contents_entry)->heading_entered->sentence_declaring->word_ref1;
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 1071 "inform7/Chapter 6/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 */
Text__print_raw_text_to_stream(h->sentence_declaring->word_ref1,
h->sentence_declaring->word_ref2, ifl);
}
INDEX("</span><span>");
heading *next = h->next_heading;
if (h->level == 0) next = h->child_heading;
int nw;
if (next) nw = next->sentence_declaring->word_ref1;
else nw = start_word + Text__Reader__sf_total_word_count(FIRST_OBJECT(source_file));
int i, N = 0;
for (i = h->sentence_declaring->word_ref1; i < nw; i++)
N += Text__Reader__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 1141 "inform7/Chapter 6/Headings.w"
nametag *nt;
int c = 0;
LOOP_OVER_NAMETAGS_UNDER(nt, h) {
int w1, w2;
Data__Nametags__get_name(nt, &w1, &w2, FALSE);
if (w1 >= 0) {
if (c++ == 0) {
Formats__HTML__open_para(ifl, ind_used+1, "hanging");
INDEX("<font color=\"#808080\">");
} else INDEX(", ");
INDEX("<i>");
Text__print_raw_text_to_stream(w1, w2, ifl);
INDEX("</i>");
}
}
if (c > 0) INDEX("</font></p>\n");
}
#line 1102 "inform7/Chapter 6/Headings.w"
;
}
#line 1058 "inform7/Chapter 6/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__doc_link("HEADINGS");
INDEX(")</p>\n");
}
}
#line 1109 "inform7/Chapter 6/Headings.w"
void 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) &&
(Text__Reader__sf_get_extension_corresponding(next->start_location.file_of_origin)))
next = NULL;
if (h->level == 0) {
show_heading = FALSE;
if ((headings_indexed == 0) &&
((next == NULL) ||
(next->sentence_declaring->word_ref1 != h->sentence_declaring->word_ref1)))
show_heading = TRUE;
}
if (Text__Reader__sf_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++;
}
index_heading_recursively(h->child_heading);
index_heading_recursively(h->next_heading);
}
#line 1170 "inform7/Chapter 6/Headings.w"
void Parser__Sentences__Headings__write_as_xml(void) {
STREAM xf_struct; STREAM *xf = &xf_struct;
char *fn = Files__Filenames__index(XML_HEADINGS_LEAFNAME, -1);
if (STREAM_OPEN_TO_FILE(xf, fn, UTF8_ENC) == FALSE)
Problems__Fatal__issue2("Can't open headings file", fn);
write_headings_as_xml_inner(xf);
STREAM_CLOSE(xf);
}
void write_headings_as_xml_inner(OUTPUT_STREAM) {
heading *h;
{
#line 1199 "inform7/Chapter 6/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 1181 "inform7/Chapter 6/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 1211 "inform7/Chapter 6/Headings.w"
if (h->start_location.file_of_origin)
WRITE("<key>Filename</key><string>%s</string>\n",
Text__Reader__sf_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>");
Text__print_raw_text_to_stream(h->sentence_declaring->word_ref1,
h->sentence_declaring->word_ref2, OUT);
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 1188 "inform7/Chapter 6/Headings.w"
;
OUTDENT;
WRITE("</dict>\n");
}
OUTDENT;
WRITE("</dict></plist>\n");
}
#line 150 "inform7/Chapter 6/Verb Phrases.w"
void Parser__Sentences__VPs__traverse(void) {
parse_node *PN;
for (TREE_START(PN); PN; TREE_NEXT(PN))
if ((Parser__Nodes__type(PN) == SENTENCE_NT) &&
(Parser__Nodes__int_annotation(PN, sentence_unparsed_ANNOT))) {
Parser__Sentences__VPs__seek(PN);
{
#line 165 "inform7/Chapter 6/Verb Phrases.w"
int w1, w2;
w1 = PN->word_ref1; w2 = PN->word_ref2;
if ((w1 >= options_file_w1) && (w2 <= options_file_w2)) {
int v = Parser__Nodes__int_annotation(PN->down, verb_id_ANNOT);
if (!((v == USE_VB) || (v == TEST_VB) || (v == DEBUG_VB) || (v == RELEASE_VB)))
Problems__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 156 "inform7/Chapter 6/Verb Phrases.w"
;
Parser__Sentences__check_sentence_for_direction_creation(PN);
Parser__Nodes__annotate_int(PN, sentence_unparsed_ANNOT, FALSE);
}
}
#line 184 "inform7/Chapter 6/Verb Phrases.w"
int assertion_NP_is_in_VP_for_to_be = FALSE;
#line 192 "inform7/Chapter 6/Verb Phrases.w"
parse_node *nss_tree_head = NULL;
binary_predicate *bp_parsed = NULL;
int certainty_parsed = UNKNOWN_CE;
int existent = FALSE;
void Parser__Sentences__VPs__seek(parse_node *PN) {
int w1, w2;
w1 = PN->word_ref1; w2 = PN->word_ref2;
certainty_parsed = UNKNOWN_CE;
bp_parsed = NULL;
nss_tree_head = PN;
existent = FALSE;
CLEAR_RW(nonstructural_sentence_NTM);
if (parse_nt_against_word_range(nonstructural_sentence_NTM, w1, w2, NULL, NULL)) {
if (existent) Parser__Nodes__annotate_int(PN, sentence_is_existential_ANNOT, TRUE);
{
#line 220 "inform7/Chapter 6/Verb Phrases.w"
switch (Parser__Nodes__int_annotation(PN->down, verb_id_ANNOT)) {
case DEBUG_VB: switch_dl_mode(PN->down->next,
Parser__Nodes__int_annotation(PN->down, log_inclusion_sense_ANNOT)); break;
case NEW_MEANINGLESS_VERB_VB: Semantics__VerbUsage__parse_new(PN); break;
case NEW_VERB_VB: Semantics__VerbUsage__parse_new(PN); break;
case NEW_RELATION_VB: Semantics__Relations__parse_new(PN); break;
}
}
#line 207 "inform7/Chapter 6/Verb Phrases.w"
;
return;
}
parse_nt_against_word_range(bad_nonstructural_sentence_diagnosis_NTM, w1, w2, NULL, NULL);
}
#line 231 "inform7/Chapter 6/Verb Phrases.w"
void switch_dl_mode(parse_node *PN, int sense) {
if (Parser__Nodes__type(PN) == AND_NT) {
switch_dl_mode(PN->down, sense);
switch_dl_mode(PN->down->next, sense);
return;
}
Log__Aspects__switch_on(PN->word_ref1, PN->word_ref2, sense);
}
#line 297 "inform7/Chapter 6/Verb Phrases.w"
int nonstructural_sentence_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = nss_tree2(R[2], nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[3]);
{
#line 410 "inform7/Chapter 6/Verb Phrases.w"
natural_language *nl = (natural_language *) (RP[2]);
Parser__Nodes__set_defn_language(nss_tree_head->down->next->next, nl);
}
#line 298 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = nss_tree2(SPECIFIES_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = nss_tree2(DEFINED_BY_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = nss_tree2(PLURAL_VB, nonstructural_sentence_NTM->range_result_w1[2], nonstructural_sentence_NTM->range_result_w2[2], RP[2], RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = nss_tree2(PLURAL_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = nss_tree2(NEW_ACTION_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 359 "inform7/Chapter 6/Verb Phrases.w"
*X = BAD_NONVERB;
Problems__assertion_problem(_P_(C6BadActionDeclaration),
"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 304 "inform7/Chapter 6/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = nss_tree2(BEGINS_WHEN_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 = nss_tree2(ENDS_WHEN_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 = nss_tree3(ENDS_WHEN_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 = nss_tree2(FIGURE_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 = nss_tree2(SOUND_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 = nss_tree2(TEST_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 = nss_tree2(UNDERSTAND_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 = nss_tree2(EPISODE_VB, nonstructural_sentence_NTM->range_result_w1[2], nonstructural_sentence_NTM->range_result_w2[2], Parser__Sentences__NPs__new_raw(nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1]), RP[1]) /* bibliographic\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15: *X = nss_tree2(FILE_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 = nss_tree2(NEW_ACTIVITY_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], Parser__Sentences__NPs__new_raw(nonstructural_sentence_NTM->range_result_w1[2], nonstructural_sentence_NTM->range_result_w2[2]));
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 17: *X = nss_tree2(NEW_VERB_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 18: *X = nss_tree1(NEW_MEANINGLESS_VERB_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[2]);
{
#line 404 "inform7/Chapter 6/Verb Phrases.w"
natural_language *nl = (natural_language *) (RP[1]);
Parser__Nodes__set_defn_language(nss_tree_head->down, nl);
}
#line 316 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 19: *X = nss_tree1(NEW_MEANINGLESS_VERB_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 20: *X = nss_tree2(NEW_VERB_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[2], RP[3]);
{
#line 404 "inform7/Chapter 6/Verb Phrases.w"
natural_language *nl = (natural_language *) (RP[1]);
Parser__Nodes__set_defn_language(nss_tree_head->down, nl);
}
#line 318 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 21: *X = nss_tree2(NEW_VERB_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 22: *X = nss_tree1(NEW_ADJ_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[2]);
{
#line 404 "inform7/Chapter 6/Verb Phrases.w"
natural_language *nl = (natural_language *) (RP[1]);
Parser__Nodes__set_defn_language(nss_tree_head->down, nl);
}
#line 320 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 23: *X = nss_tree2(NEW_ADJ_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[2], RP[3]);
{
#line 404 "inform7/Chapter 6/Verb Phrases.w"
natural_language *nl = (natural_language *) (RP[1]);
Parser__Nodes__set_defn_language(nss_tree_head->down, nl);
}
#line 321 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 24: *X = nss_tree2(CANBE_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 25: *X = nss_tree2(CANBE_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 26: *X = nss_tree2(IN_RULEBOOK_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 27: *X = nss_tree2(NOT_IN_RULEBOOK_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 28: *X = nss_tree1(NO_EFFECT_AT_ALL_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 29: *X = nss_tree2(NO_EFFECT_IF_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 30: *X = nss_tree2(NO_EFFECT_UNLESS_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 31: *X = nss_tree2(SUBSTITUTES_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 32: *X = nss_tree3(SUBSTITUTES_IF_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 = nss_tree3(SUBSTITUTES_UNLESS_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 = nss_tree3(NEW_RELATION_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 347 "inform7/Chapter 6/Verb Phrases.w"
*X = BAD_NONVERB;
Problems__sentence_problem(_P_(C6CanHave),
"'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 333 "inform7/Chapter 6/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 368 "inform7/Chapter 6/Verb Phrases.w"
int s1, s2, v1, v2, o1, o2;
GET_RW(regular_sentence_NTM, 1, s1, s2);
GET_RW(regular_sentence_NTM, 2, v1, v2);
GET_RW(regular_sentence_NTM, 3, o1, o2);
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 = Parser__Nodes__new(VERB_NT);
VP_PN->word_ref1 = v1; VP_PN->word_ref2 = v2;
if (certainty_parsed != UNKNOWN_CE)
Parser__Nodes__annotate_int(VP_PN, verbal_certainty_ANNOT, certainty_parsed);
int t = R[1], altered = FALSE;
if (t < 0) { t = -t; altered = TRUE; }
Parser__Nodes__annotate_int(VP_PN, verb_id_ANNOT, t);
Parser__Nodes__graft(VP_PN, nss_tree_head);
parse_node *np1 = NULL;
if (parse_nt_against_word_range(nounphrase_as_subject_NTM, s1, s2, NULL, NULL) == FALSE) return FALSE; /* shouldn't ever happen */
np1 = most_recent_result_p;
Parser__Nodes__graft(np1, nss_tree_head);
parse_node *np2 = NULL;
if (parse_nt_against_word_range(nounphrase_as_object_NTM, o1, o2, NULL, NULL) == FALSE) return FALSE; /* shouldn't ever happen */
np2 = most_recent_result_p;
Parser__Nodes__graft(np2, nss_tree_head);
assertion_NP_is_in_VP_for_to_be = save;
{
#line 428 "inform7/Chapter 6/Verb Phrases.w"
if ((t == ASSERT_VB) && ((altered == FALSE) || (bp_parsed != R_equality))) {
parse_node *REL_PN = Parser__Nodes__new(RELATIONSHIP_NT);
REL_PN->word_ref1 = v1; REL_PN->word_ref2 = v2;
Parser__Nodes__set_relationship(REL_PN, Semantics__BPs__get_reversal(bp_parsed));
np1->next = REL_PN; REL_PN->down = np2;
}
}
#line 398 "inform7/Chapter 6/Verb Phrases.w"
;
*X = 0;
}
#line 334 "inform7/Chapter 6/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 37:
{
#line 368 "inform7/Chapter 6/Verb Phrases.w"
int s1, s2, v1, v2, o1, o2;
GET_RW(regular_sentence_NTM, 1, s1, s2);
GET_RW(regular_sentence_NTM, 2, v1, v2);
GET_RW(regular_sentence_NTM, 3, o1, o2);
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 = Parser__Nodes__new(VERB_NT);
VP_PN->word_ref1 = v1; VP_PN->word_ref2 = v2;
if (certainty_parsed != UNKNOWN_CE)
Parser__Nodes__annotate_int(VP_PN, verbal_certainty_ANNOT, certainty_parsed);
int t = R[1], altered = FALSE;
if (t < 0) { t = -t; altered = TRUE; }
Parser__Nodes__annotate_int(VP_PN, verb_id_ANNOT, t);
Parser__Nodes__graft(VP_PN, nss_tree_head);
parse_node *np1 = NULL;
if (parse_nt_against_word_range(nounphrase_as_subject_NTM, s1, s2, NULL, NULL) == FALSE) return FALSE; /* shouldn't ever happen */
np1 = most_recent_result_p;
Parser__Nodes__graft(np1, nss_tree_head);
parse_node *np2 = NULL;
if (parse_nt_against_word_range(nounphrase_as_object_NTM, o1, o2, NULL, NULL) == FALSE) return FALSE; /* shouldn't ever happen */
np2 = most_recent_result_p;
Parser__Nodes__graft(np2, nss_tree_head);
assertion_NP_is_in_VP_for_to_be = save;
{
#line 428 "inform7/Chapter 6/Verb Phrases.w"
if ((t == ASSERT_VB) && ((altered == FALSE) || (bp_parsed != R_equality))) {
parse_node *REL_PN = Parser__Nodes__new(RELATIONSHIP_NT);
REL_PN->word_ref1 = v1; REL_PN->word_ref2 = v2;
Parser__Nodes__set_relationship(REL_PN, Semantics__BPs__get_reversal(bp_parsed));
np1->next = REL_PN; REL_PN->down = np2;
}
}
#line 398 "inform7/Chapter 6/Verb Phrases.w"
;
*X = 0;
}
#line 335 "inform7/Chapter 6/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 38: *X = nss_tree2(USEMEANS_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 39: *X = nss_tree1(USE_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 40: *X = nss_tree1(RELEASE_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 41: *X = nss_tree1(MAP_PARAMETER_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 42: *X = nss_tree1(DEBUG_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1]); Parser__Nodes__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 = nss_tree1(DEBUG_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[1], RP[1]); Parser__Nodes__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 = nss_tree2(DOC_VB, nonstructural_sentence_NTM->range_result_w1[1], nonstructural_sentence_NTM->range_result_w2[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 343 "inform7/Chapter 6/Verb Phrases.w"
#line 447 "inform7/Chapter 6/Verb Phrases.w"
int nss_tree1(int t, int verb_w1, int verb_w2, parse_node *np1) {
parse_node *VP_PN = Parser__Nodes__new(VERB_NT);
VP_PN->word_ref1 = verb_w1; VP_PN->word_ref2 = verb_w2;
Parser__Nodes__annotate_int(VP_PN, verb_id_ANNOT, t);
Parser__Nodes__graft(VP_PN, nss_tree_head);
Parser__Nodes__graft(np1, nss_tree_head);
return 0;
}
int nss_tree2(int t, int verb_w1, int verb_w2, parse_node *np1, parse_node *np2) {
parse_node *VP_PN = Parser__Nodes__new(VERB_NT);
VP_PN->word_ref1 = verb_w1; VP_PN->word_ref2 = verb_w2;
Parser__Nodes__annotate_int(VP_PN, verb_id_ANNOT, t);
Parser__Nodes__graft(VP_PN, nss_tree_head);
Parser__Nodes__graft(np1, nss_tree_head);
Parser__Nodes__graft(np2, nss_tree_head);
return 0;
}
int nss_tree3(int t, int verb_w1, int verb_w2, parse_node *np1, parse_node *np2, parse_node *np3) {
parse_node *VP_PN = Parser__Nodes__new(VERB_NT);
VP_PN->word_ref1 = verb_w1; VP_PN->word_ref2 = verb_w2;
Parser__Nodes__annotate_int(VP_PN, verb_id_ANNOT, t);
Parser__Nodes__graft(VP_PN, nss_tree_head);
Parser__Nodes__graft(np1, nss_tree_head);
Parser__Nodes__graft(np2, nss_tree_head);
Parser__Nodes__graft(np3, nss_tree_head);
return 0;
}
#line 496 "inform7/Chapter 6/Verb Phrases.w"
int nounphrase_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 498 "inform7/Chapter 6/Verb Phrases.w"
int nounphrase_definite_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 502 "inform7/Chapter 6/Verb Phrases.w"
int nounphrase_figure_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 505 "inform7/Chapter 6/Verb Phrases.w"
int nounphrase_sound_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 508 "inform7/Chapter 6/Verb Phrases.w"
int nounphrase_external_file_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 511 "inform7/Chapter 6/Verb Phrases.w"
int nounphrase_actionable_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 514 "inform7/Chapter 6/Verb Phrases.w"
int variable_creation_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 518 "inform7/Chapter 6/Verb Phrases.w"
#line 522 "inform7/Chapter 6/Verb Phrases.w"
int translation_target_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 527 "inform7/Chapter 6/Verb Phrases.w"
#line 549 "inform7/Chapter 6/Verb Phrases.w"
int existential_sentence_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 656 "inform7/Chapter 6/Verb Phrases.w"
*X = BAD_NONVERB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
Problems__sentence_problem(_P_(C6TwoLikelihoods),
"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 552 "inform7/Chapter 6/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 = Semantics__PrepositionUsage__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 = Semantics__PrepositionUsage__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 = Semantics__PrepositionUsage__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 559 "inform7/Chapter 6/Verb Phrases.w"
#line 573 "inform7/Chapter 6/Verb Phrases.w"
int existential_sentence_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 596 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail1_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail1_inner_NTM, 2, c1, c2);
PUT_RW(existential_sentence_inner_NTM, 2, b1, b2);
PUT_RW(existential_sentence_inner_NTM, 3, c1, c2);
}
#line 574 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 606 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail2_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail2_inner_NTM, 2, c1, c2);
PUT_RW(existential_sentence_inner_NTM, 2, b1, b2);
PUT_RW(existential_sentence_inner_NTM, 3, c1, c2);
}
#line 575 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 616 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail3_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail3_inner_NTM, 2, c1, c2);
PUT_RW(existential_sentence_inner_NTM, 2, b1, b2);
PUT_RW(existential_sentence_inner_NTM, 3, c1, c2);
}
#line 576 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 596 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail1_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail1_inner_NTM, 2, c1, c2);
PUT_RW(existential_sentence_inner_NTM, 2, b1, b2);
PUT_RW(existential_sentence_inner_NTM, 3, c1, c2);
}
#line 577 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 606 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail2_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail2_inner_NTM, 2, c1, c2);
PUT_RW(existential_sentence_inner_NTM, 2, b1, b2);
PUT_RW(existential_sentence_inner_NTM, 3, c1, c2);
}
#line 578 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 616 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail3_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail3_inner_NTM, 2, c1, c2);
PUT_RW(existential_sentence_inner_NTM, 2, b1, b2);
PUT_RW(existential_sentence_inner_NTM, 3, c1, c2);
}
#line 579 "inform7/Chapter 6/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 580 "inform7/Chapter 6/Verb Phrases.w"
int existential_sentence_inner_tail1_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + existential_sentence_inner_tail1_NTM->range_result_w1[1] - w1;;
#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 6/Verb Phrases.w"
int existential_sentence_inner_tail2_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + existential_sentence_inner_tail2_NTM->range_result_w1[1] - w1;;
#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 6/Verb Phrases.w"
int existential_sentence_inner_tail3_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + existential_sentence_inner_tail3_NTM->range_result_w1[1] - w1;;
#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 592 "inform7/Chapter 6/Verb Phrases.w"
#line 646 "inform7/Chapter 6/Verb Phrases.w"
int certainty_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 652 "inform7/Chapter 6/Verb Phrases.w"
#line 704 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 811 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail1_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail1_inner_NTM, 2, c1, c2);
PUT_RW(regular_sentence_NTM, 2, b1, b2);
PUT_RW(regular_sentence_NTM, 3, c1, c2);
}
#line 705 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 821 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail2_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail2_inner_NTM, 2, c1, c2);
PUT_RW(regular_sentence_NTM, 2, b1, b2);
PUT_RW(regular_sentence_NTM, 3, c1, c2);
}
#line 706 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 831 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail3_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail3_inner_NTM, 2, c1, c2);
PUT_RW(regular_sentence_NTM, 2, b1, b2);
PUT_RW(regular_sentence_NTM, 3, c1, c2);
}
#line 707 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 841 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail4_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail4_inner_NTM, 2, c1, c2);
PUT_RW(regular_sentence_NTM, 2, b1, b2);
PUT_RW(regular_sentence_NTM, 3, c1, c2);
}
#line 708 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 811 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail1_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail1_inner_NTM, 2, c1, c2);
PUT_RW(regular_sentence_NTM, 2, b1, b2);
PUT_RW(regular_sentence_NTM, 3, c1, c2);
}
#line 709 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 821 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail2_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail2_inner_NTM, 2, c1, c2);
PUT_RW(regular_sentence_NTM, 2, b1, b2);
PUT_RW(regular_sentence_NTM, 3, c1, c2);
}
#line 710 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 831 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail3_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail3_inner_NTM, 2, c1, c2);
PUT_RW(regular_sentence_NTM, 2, b1, b2);
PUT_RW(regular_sentence_NTM, 3, c1, c2);
}
#line 711 "inform7/Chapter 6/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7:
{
#line 841 "inform7/Chapter 6/Verb Phrases.w"
*X = R[1];
int b1, b2, c1, c2;
GET_RW(regular_sentence_tail4_inner_NTM, 1, b1, b2);
GET_RW(regular_sentence_tail4_inner_NTM, 2, c1, c2);
PUT_RW(regular_sentence_NTM, 2, b1, b2);
PUT_RW(regular_sentence_NTM, 3, c1, c2);
}
#line 712 "inform7/Chapter 6/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 713 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail1_without_rc_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail1_without_rc_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail1_without_rc_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail1_without_rc_NTM->range_result_w1[1] - w1;;
#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 719 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail2_without_rc_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail2_without_rc_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail2_without_rc_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail2_without_rc_NTM->range_result_w1[1] - w1;;
#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 725 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail3_without_rc_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail3_without_rc_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail3_without_rc_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail3_without_rc_NTM->range_result_w1[1] - w1;;
#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 731 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail4_without_rc_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail4_without_rc_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail4_without_rc_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail4_without_rc_NTM->range_result_w1[1] - w1;;
#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 737 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail1_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail1_NTM->range_result_w1[1] - w1;;
#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 741 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail2_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail2_NTM->range_result_w1[1] - w1;;
#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 745 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail3_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail3_NTM->range_result_w1[1] - w1;;
#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 749 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail4_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + regular_sentence_tail4_NTM->range_result_w1[1] - w1;;
#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 753 "inform7/Chapter 6/Verb Phrases.w"
#line 784 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail1_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 656 "inform7/Chapter 6/Verb Phrases.w"
*X = BAD_NONVERB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
Problems__sentence_problem(_P_(C6TwoLikelihoods),
"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 785 "inform7/Chapter 6/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 789 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail2_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 656 "inform7/Chapter 6/Verb Phrases.w"
*X = BAD_NONVERB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
Problems__sentence_problem(_P_(C6TwoLikelihoods),
"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 791 "inform7/Chapter 6/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 795 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail3_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 656 "inform7/Chapter 6/Verb Phrases.w"
*X = BAD_NONVERB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
Problems__sentence_problem(_P_(C6TwoLikelihoods),
"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 797 "inform7/Chapter 6/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 = Semantics__VerbUsage__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 = Semantics__VerbUsage__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 = Semantics__VerbUsage__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 801 "inform7/Chapter 6/Verb Phrases.w"
int regular_sentence_tail4_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 656 "inform7/Chapter 6/Verb Phrases.w"
*X = BAD_NONVERB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
Problems__sentence_problem(_P_(C6TwoLikelihoods),
"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 803 "inform7/Chapter 6/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 = Semantics__VerbUsage__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 = Semantics__VerbUsage__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 = Semantics__VerbUsage__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 807 "inform7/Chapter 6/Verb Phrases.w"
#line 853 "inform7/Chapter 6/Verb Phrases.w"
int bad_nonstructural_sentence_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 855 "inform7/Chapter 6/Verb Phrases.w"
int bad_nonstructural_sentence_diagnosis_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + bad_nonstructural_sentence_diagnosis_tail_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + bad_nonstructural_sentence_diagnosis_tail_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 865 "inform7/Chapter 6/Verb Phrases.w"
if (Parser__Nodes__int_annotation(current_sentence, verb_problem_issued_ANNOT) == FALSE) {
Parser__Nodes__annotate_int(current_sentence, verb_problem_issued_ANNOT, TRUE);
Problems__sentence_problem(_P_(C6NonPresentTense),
"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 859 "inform7/Chapter 6/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 878 "inform7/Chapter 6/Verb Phrases.w"
if (Parser__Nodes__int_annotation(current_sentence, verb_problem_issued_ANNOT) == FALSE) {
Parser__Nodes__annotate_int(current_sentence, verb_problem_issued_ANNOT, TRUE);
Problems__negative_sentence_problem(_P_(C6NegatedVerb1));
}
}
#line 860 "inform7/Chapter 6/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 861 "inform7/Chapter 6/Verb Phrases.w"
#line 886 "inform7/Chapter 6/Verb Phrases.w"
void Parser__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 6/Noun Phrases.w"
parse_node *Parser__Sentences__NPs__new_raw(int w1, int w2) {
parse_node *PN;
PN = Parser__Nodes__new(PROPER_NOUN_NT);
Parser__Nodes__annotate_int(PN, nounphrase_article_ANNOT, NO_ART);
PN->word_ref1 = w1; PN->word_ref2 = w2;
return PN;
}
#line 69 "inform7/Chapter 6/Noun Phrases.w"
int nounphrase_articled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 78 "inform7/Chapter 6/Noun Phrases.w"
Parser__Nodes__annotate_int(*XP, nounphrase_article_ANNOT, INDEF_ART);
Parser__Nodes__annotate_int(*XP, plural_reference_ANNOT, (R[2] >= 3)?TRUE:FALSE);
Parser__Nodes__annotate_int(*XP, gender_reference_ANNOT, (R[2] % 3) + 1);
}
#line 71 "inform7/Chapter 6/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 85 "inform7/Chapter 6/Noun Phrases.w"
Parser__Nodes__annotate_int(*XP, nounphrase_article_ANNOT, DEF_ART);
Parser__Nodes__annotate_int(*XP, plural_reference_ANNOT, (R[2] >= 3)?TRUE:FALSE);
Parser__Nodes__annotate_int(*XP, gender_reference_ANNOT, (R[2] % 3) + 1);
}
#line 72 "inform7/Chapter 6/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 74 "inform7/Chapter 6/Noun Phrases.w"
#line 93 "inform7/Chapter 6/Noun Phrases.w"
int np_balanced_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 96 "inform7/Chapter 6/Noun Phrases.w"
int np_articled_balanced_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 100 "inform7/Chapter 6/Noun Phrases.w"
#line 112 "inform7/Chapter 6/Noun Phrases.w"
parse_node *Parser__Sentences__NPs__annotate_by_articles(parse_node *RAW_NP) {
parse_nt_against_word_range(nounphrase_articled_NTM, RAW_NP->word_ref1, RAW_NP->word_ref2, NULL, NULL);
parse_node *MODEL = most_recent_result_p;
RAW_NP->word_ref1 = MODEL->word_ref1; RAW_NP->word_ref2 = MODEL->word_ref2;
Parser__Nodes__annotate_int(RAW_NP, nounphrase_article_ANNOT,
Parser__Nodes__int_annotation(MODEL, nounphrase_article_ANNOT));
Parser__Nodes__annotate_int(RAW_NP, plural_reference_ANNOT,
Parser__Nodes__int_annotation(MODEL, plural_reference_ANNOT));
return RAW_NP;
}
#line 130 "inform7/Chapter 6/Noun Phrases.w"
int nounphrase_articled_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = PN_pair(AND_NT, R[2], 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 134 "inform7/Chapter 6/Noun Phrases.w"
int np_articled_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = w1; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = w1; *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 138 "inform7/Chapter 6/Noun Phrases.w"
#line 159 "inform7/Chapter 6/Noun Phrases.w"
int nounphrase_rule_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = PN_pair(AND_NT, R[2], 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 163 "inform7/Chapter 6/Noun Phrases.w"
int np_rule_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = w1; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = w1; *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 6/Noun Phrases.w"
int nounphrase_rule_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = Parser__Sentences__NPs__new_raw(w1, w2);
#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 6/Noun Phrases.w"
#line 178 "inform7/Chapter 6/Noun Phrases.w"
int nounphrase_alternative_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = PN_pair(AND_NT, R[2], 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 182 "inform7/Chapter 6/Noun Phrases.w"
int np_alternative_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = w1; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = w1; *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 6/Noun Phrases.w"
#line 202 "inform7/Chapter 6/Noun Phrases.w"
int nounphrase_as_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 205 "inform7/Chapter 6/Noun Phrases.w"
int nounphrase_as_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 210 "inform7/Chapter 6/Noun Phrases.w"
int np_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 214 "inform7/Chapter 6/Noun Phrases.w"
#line 219 "inform7/Chapter 6/Noun Phrases.w"
int if_copular_NTMR(int w1, int w2, int *X, void **XP) {
#line 220 "inform7/Chapter 6/Noun Phrases.w"
return assertion_NP_is_in_VP_for_to_be;
}
#line 258 "inform7/Chapter 6/Noun Phrases.w"
int np_relative_phrase_limited_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 263 "inform7/Chapter 6/Noun Phrases.w"
int np_relative_phrase_unlimited_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 268 "inform7/Chapter 6/Noun Phrases.w"
#line 278 "inform7/Chapter 6/Noun Phrases.w"
int np_relative_phrase_exception_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 280 "inform7/Chapter 6/Noun Phrases.w"
#line 297 "inform7/Chapter 6/Noun Phrases.w"
int np_relative_phrase_implicit_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = PN_rel(w1, w2, 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 = PN_rel(w1, w2, 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 = PN_rel(w1, w2, 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 = PN_rel(w1, w2, 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 302 "inform7/Chapter 6/Noun Phrases.w"
int np_relative_phrase_explicit_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = PN_rel(w1, w2, Semantics__BPs__get_reversal(Semantics__PrepositionUsage__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 307 "inform7/Chapter 6/Noun Phrases.w"
#line 382 "inform7/Chapter 6/Noun Phrases.w"
int np_inner_without_rp_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = PN_pair(CALLED_NT, np_inner_without_rp_NTM->range_result_w1[1], np_inner_without_rp_NTM->range_result_w2[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 = PN_pair(WITH_NT, R[2], 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 = PN_pair(AND_NT, R[2], 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 = PN_pair(R[2], w1, w2, RP[2], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = 0; *XP = Parser__Sentences__NPs__new_raw(w1, w2); Parser__Nodes__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 391 "inform7/Chapter 6/Noun Phrases.w"
#line 408 "inform7/Chapter 6/Noun Phrases.w"
int np_with_or_having_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + np_with_or_having_tail_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + np_with_or_having_tail_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = np_with_or_having_tail_NTM->range_result_w1[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 412 "inform7/Chapter 6/Noun Phrases.w"
int np_new_property_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = PN_pair(AND_NT, R[2], 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 417 "inform7/Chapter 6/Noun Phrases.w"
int np_new_property_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = PN_void(PROPERTY_LIST_NT, w1, w2);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 420 "inform7/Chapter 6/Noun Phrases.w"
int np_new_property_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = w1; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = w1; *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 424 "inform7/Chapter 6/Noun Phrases.w"
int np_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = w1; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = w1; *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 428 "inform7/Chapter 6/Noun Phrases.w"
#line 437 "inform7/Chapter 6/Noun Phrases.w"
int np_kind_phrase_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 440 "inform7/Chapter 6/Noun Phrases.w"
int np_kind_phrase_unarticled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = PN_void(KIND_NT, w1, w2);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = PN_single(KIND_NT, w1, w2, 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 444 "inform7/Chapter 6/Noun Phrases.w"
#line 454 "inform7/Chapter 6/Noun Phrases.w"
int np_from_or_of_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + np_from_or_of_tail_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + np_from_or_of_tail_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + np_from_or_of_tail_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; return FAIL_NONTERMINAL + np_from_or_of_tail_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = X_OF_Y_NT; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = FROM_NT; *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 461 "inform7/Chapter 6/Noun Phrases.w"
#line 467 "inform7/Chapter 6/Noun Phrases.w"
parse_node *PN_void(int t, int w1, int w2) {
if (preform_lookahead_mode) return NULL;
parse_node *P = Parser__Nodes__new(t);
P->word_ref1 = w1; P->word_ref2 = w2;
return P;
}
parse_node *PN_single(int t, int w1, int w2, parse_node *A) {
if (preform_lookahead_mode) return NULL;
parse_node *P = Parser__Nodes__new(t);
P->word_ref1 = w1; P->word_ref2 = w2;
P->down = A;
return P;
}
parse_node *PN_pair(int t, int w1, int w2, parse_node *A, parse_node *B) {
if (preform_lookahead_mode) return NULL;
parse_node *P = Parser__Nodes__new(t);
P->word_ref1 = w1; P->word_ref2 = w2;
P->down = A; P->down->next = B;
return P;
}
#line 498 "inform7/Chapter 6/Noun Phrases.w"
parse_node *PN_rel(int w1, int w2, binary_predicate *R, int reln_type, parse_node *referent) {
if (preform_lookahead_mode) return NULL;
parse_node *P = Parser__Nodes__new(RELATIONSHIP_NT);
P->word_ref1 = w1; P->word_ref2 = w2;
if (R) Parser__Nodes__set_relationship(P, R);
else if (reln_type >= 0)
Parser__Nodes__annotate_int(P, relationship_node_type_ANNOT, reln_type);
else internal_error("undefined relationship node");
if (referent == NULL) {
referent = Parser__Sentences__NPs__new_raw(w1, w2);
Parser__Nodes__annotate_int(referent, implicitly_refers_to_ANNOT, TRUE);
}
P->down = referent;
return P;
}
#line 525 "inform7/Chapter 6/Noun Phrases.w"
int Parser__Sentences__NPs__turn_player_to_yourself(parse_node *pn) {
if ((pn->word_ref1 >= 0) &&
(Parser__Nodes__type(pn) == PROPER_NOUN_NT) &&
(Parser__Nodes__int_annotation(pn, turned_already_ANNOT) == FALSE)) {
nonlocal_variable *q = Data__NonlocalVariables__parse(pn->word_ref1, pn->word_ref2);
inference_subject *diversion = Data__NonlocalVariables__get_alias(q);
if (diversion) {
Parser__Nodes__noun_from_infs(pn, diversion);
Parser__Nodes__annotate_int(pn, turned_already_ANNOT, TRUE);
return TRUE;
}
}
return FALSE;
}
#line 62 "inform7/Chapter 6/Of and From.w"
void expunge_X_OF_Y_subtree(parse_node *pn) {
Parser__Nodes__set_node_type(pn, PROPER_NOUN_NT);
pn->down = NULL;
Parser__Sentences__NPs__annotate_by_articles(pn);
}
void expunge_FROM_subtree(parse_node *pn) {
Parser__Nodes__set_node_type(pn, PROPER_NOUN_NT);
pn->down = NULL;
Parser__Sentences__NPs__annotate_by_articles(pn);
}
#line 85 "inform7/Chapter 6/Of and From.w"
void convert_clause_to_RELATIONSHIP(parse_node *pn) {
Parser__Nodes__set_node_type(pn, RELATIONSHIP_NT);
Parser__Nodes__annotate_int(pn, relationship_node_type_ANNOT, DIRECTION_RELN);
}
#line 114 "inform7/Chapter 6/Of and From.w"
void Parser__Sentences__tidy_up_ofs_and_froms(void) {
Parser__Nodes__verify_integrity(tree_root, FALSE);
traverse_for_property_names(tree_root->down);
traverse_for_nonbreaking_ofs(tree_root->down);
traverse_for_FROM_NT_subtrees(tree_root->down);
}
#line 127 "inform7/Chapter 6/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 6/Of and From.w"
void traverse_for_property_names(parse_node *pn) {
for (; pn; pn = pn->next) {
switch(Parser__Nodes__type(pn)) {
case SENTENCE_NT: current_sentence = pn; break;
case VERB_NT:
{
#line 201 "inform7/Chapter 6/Of and From.w"
if ((Parser__Nodes__int_annotation(pn, verb_id_ANNOT) == HAS_VB)
&& (pn->next)
&& (pn->next->next)
&& (Parser__Nodes__type(pn->next->next) == CALLED_NT)
&& (pn->next->next->down)
&& (pn->next->next->down->next)) {
parse_node *apparent_subject = pn->next;
int s1 = apparent_subject->word_ref1, s2 = apparent_subject->word_ref2;
if (Parser__Nodes__type(apparent_subject) == WITH_NT)
if (apparent_subject->down) {
s1 = apparent_subject->down->word_ref1;
if (apparent_subject->down->next)
s2 = apparent_subject->down->next->word_ref2;
}
if (parse_nt_against_word_range(prohibited_property_owners_NTM, s1, s2, NULL, NULL) == FALSE) {
int w1, w2;
w1 = pn->next->next->down->next->word_ref1; w2 = pn->next->next->down->next->word_ref2;
parse_nt_against_word_range(has_properties_called_sentence_object_NTM, w1, w2, NULL, NULL);
}
}
}
#line 145 "inform7/Chapter 6/Of and From.w"
;
break;
}
traverse_for_property_names(pn->down);
}
}
#line 155 "inform7/Chapter 6/Of and From.w"
void Parser__Sentences__check_sentence_for_direction_creation(parse_node *pn) {
if (Parser__Nodes__type(pn) != SENTENCE_NT) return;
if ((pn->down == NULL) || (pn->down->next == NULL) || (pn->down->next->next == NULL)) return;
if (Parser__Nodes__type(pn->down) != VERB_NT) return;
if (Parser__Nodes__type(pn->down->next) != PROPER_NOUN_NT) return;
if (Parser__Nodes__type(pn->down->next->next) != PROPER_NOUN_NT) return;
current_sentence = pn;
pn = pn->down->next;
if (!((parse_nt_against_word_range(notable_map_kinds_NTM, pn->next->word_ref1, pn->next->word_ref2, NULL, NULL))
&& (most_recent_result == 0))) return;
if (no_directions_noticed >= MAX_DIRECTIONS) {
Problems__limit_problem(_P_(C6TooManyDirections),
"different directions", MAX_DIRECTIONS);
return;
}
direction_relations_noticed[no_directions_noticed] =
Plugins__Map__create_sketchy_mapping_direction(pn->word_ref1, pn->word_ref2);
directions_noticed[no_directions_noticed++] = pn;
}
#line 178 "inform7/Chapter 6/Of and From.w"
binary_predicate *Parser__Sentences__relation_noticed(int i) {
return direction_relations_noticed[i];
}
#line 232 "inform7/Chapter 6/Of and From.w"
int prohibited_property_owners_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 236 "inform7/Chapter 6/Of and From.w"
#line 242 "inform7/Chapter 6/Of and From.w"
int action_name_formal_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 244 "inform7/Chapter 6/Of and From.w"
int activity_name_formal_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 247 "inform7/Chapter 6/Of and From.w"
int relation_name_formal_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 250 "inform7/Chapter 6/Of and From.w"
int rule_name_formal_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 253 "inform7/Chapter 6/Of and From.w"
int rulebook_name_formal_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 256 "inform7/Chapter 6/Of and From.w"
#line 267 "inform7/Chapter 6/Of and From.w"
int has_properties_called_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 270 "inform7/Chapter 6/Of and From.w"
int has_property_name_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 274 "inform7/Chapter 6/Of and From.w"
int has_property_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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(w1, w2);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 278 "inform7/Chapter 6/Of and From.w"
int bad_property_name_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 288 "inform7/Chapter 6/Of and From.w"
Problems__sentence_problem(_P_(C6PropertyCalledArticle),
"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 280 "inform7/Chapter 6/Of and From.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 296 "inform7/Chapter 6/Of and From.w"
Problems__sentence_problem(_P_(C6PropertyCalledPresence),
"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 281 "inform7/Chapter 6/Of and From.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 307 "inform7/Chapter 6/Of and From.w"
Problems__sentence_problem(_P_(C6PropertyNameForbidden),
"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 282 "inform7/Chapter 6/Of and From.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 307 "inform7/Chapter 6/Of and From.w"
Problems__sentence_problem(_P_(C6PropertyNameForbidden),
"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 283 "inform7/Chapter 6/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 284 "inform7/Chapter 6/Of and From.w"
#line 335 "inform7/Chapter 6/Of and From.w"
int sentence_needing_second_look_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 337 "inform7/Chapter 6/Of and From.w"
#line 341 "inform7/Chapter 6/Of and From.w"
void traverse_for_nonbreaking_ofs(parse_node *pn) {
for (; pn; pn = pn->next) {
if ((Parser__Nodes__type(pn) == SENTENCE_NT) &&
(pn->down) && (Parser__Nodes__type(pn->down) == VERB_NT)) {
int vn = Parser__Nodes__int_annotation(pn->down, verb_id_ANNOT);
if (((vn == ASSERT_VB) || (vn == HAS_VB) || (vn == DEFINED_BY_VB)) &&
(parse_nt_against_word_range(sentence_needing_second_look_NTM, pn->word_ref1, pn->word_ref2, NULL, NULL))) {
current_sentence = pn; /* (just in case any problem messages are issued) */
pn->down = NULL; /* thus cutting off and forgetting its former subtree */
Parser__Sentences__VPs__seek(pn); /* ...in order to make a new one */
}
}
}
}
#line 377 "inform7/Chapter 6/Of and From.w"
void traverse_for_FROM_NT_subtrees(parse_node *pn) {
for (; pn; pn = pn->next) {
traverse_for_FROM_NT_subtrees(pn->down);
switch(Parser__Nodes__type(pn)) {
case SENTENCE_NT: current_sentence = pn; break;
case FROM_NT:
if ((pn->down) && (pn->down->next)) {
int direction_found = FALSE;
{
#line 409 "inform7/Chapter 6/Of and From.w"
int i, w1, w2;
w1 = pn->down->next->word_ref1; w2 = pn->down->next->word_ref2;
if (Text__unexpectedly_upper_case(w1) == FALSE)
for (i=0; i<no_directions_noticed; i++)
if (Text__compare_word_range(w1, w2,
directions_noticed[i]->word_ref1, directions_noticed[i]->word_ref2))
direction_found = TRUE;
if (direction_found) convert_clause_to_RELATIONSHIP(pn);
}
#line 385 "inform7/Chapter 6/Of and From.w"
;
if (direction_found == FALSE) 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, w1, w2;
w1 = pn->down->next->word_ref1; w2 = pn->down->next->word_ref2;
if (parse_nt_against_word_range(property_name_NTM, w1, w2, NULL, NULL)) allow_this = TRUE;
{
#line 409 "inform7/Chapter 6/Of and From.w"
int i, w1, w2;
w1 = pn->down->next->word_ref1; w2 = pn->down->next->word_ref2;
if (Text__unexpectedly_upper_case(w1) == FALSE)
for (i=0; i<no_directions_noticed; i++)
if (Text__compare_word_range(w1, w2,
directions_noticed[i]->word_ref1, directions_noticed[i]->word_ref2))
direction_found = TRUE;
if (direction_found) convert_clause_to_RELATIONSHIP(pn);
}
#line 394 "inform7/Chapter 6/Of and From.w"
;
if ((allow_this == FALSE) && (direction_found == FALSE))
expunge_X_OF_Y_subtree(pn);
} else internal_error("malformed X_OF_Y_NT subtree");
break;
}
}
}
#line 60 "inform7/Chapter 6/Rule Subtrees.w"
void Parser__Sentences__register_recently_lexed_phrases(void) {
parse_node *p;
if (problem_count > 0) return; /* for then the tree is perhaps broken anyway */
for (p = tree_root->down; p; p=p->next)
if ((Parser__Nodes__type(p) == ROUTINE_NT) && (p->down == NULL)) {
parse_node *end_def = p;
while ((end_def->next) && (Parser__Nodes__type(end_def->next) == COMMAND_NT))
end_def = end_def->next;
if (p == end_def) continue; /* |ROUTINE_NT| not followed by any |COMMAND_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;
unify_block_syntaxes(p);
}
{
#line 81 "inform7/Chapter 6/Rule Subtrees.w"
for (p = tree_root->down; p; p=p->next)
if (Parser__Nodes__type(p) == COMMAND_NT) {
current_sentence = p;
internal_error("loose COMMAND node outside of rule definition");
}
}
#line 75 "inform7/Chapter 6/Rule Subtrees.w"
;
}
#line 93 "inform7/Chapter 6/Rule Subtrees.w"
void unify_block_syntaxes(parse_node *rout) {
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 164 "inform7/Chapter 6/Rule Subtrees.w"
parse_node *p;
for (p = rout->down; p; p = p->next) {
control_structure_phrase *csp =
Parser__Sentences__detect_control_structure(p->word_ref1, p->word_ref2);
if (csp) {
int syntax_used = Parser__Nodes__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) &&
(!(parse_nt_against_word_range(phrase_beginning_block_NTM, p->word_ref1, p->word_ref2, 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 193 "inform7/Chapter 6/Rule Subtrees.w"
if ((uses_begin_end_syntax == NULL) && (mispunctuates_begin_end_syntax == NULL)) {
if (parse_nt_against_word_range(phrase_beginning_block_NTM, p->word_ref1, p->word_ref2, NULL, NULL))
uses_begin_end_syntax = p;
else
mispunctuates_begin_end_syntax = p;
}
}
#line 180 "inform7/Chapter 6/Rule Subtrees.w"
;
}
}
if ((csp->requires_new_syntax) && (requires_colon_syntax == NULL))
requires_colon_syntax = p;
}
if (parse_nt_against_word_range(end_control_structure_phrase_NTM, p->word_ref1, p->word_ref2, NULL, NULL))
{
#line 193 "inform7/Chapter 6/Rule Subtrees.w"
if ((uses_begin_end_syntax == NULL) && (mispunctuates_begin_end_syntax == NULL)) {
if (parse_nt_against_word_range(phrase_beginning_block_NTM, p->word_ref1, p->word_ref2, NULL, NULL))
uses_begin_end_syntax = p;
else
mispunctuates_begin_end_syntax = p;
}
}
#line 187 "inform7/Chapter 6/Rule Subtrees.w"
;
}
}
#line 99 "inform7/Chapter 6/Rule Subtrees.w"
;
if ((uses_colon_syntax) && (mispunctuates_begin_end_syntax)) {
current_sentence = rout;
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, mispunctuates_begin_end_syntax);
Problems__handmade_problem(_P_(C6BadOldSyntax));
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 = rout;
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, uses_colon_syntax);
Problems__quote_source(3, uses_begin_end_syntax);
Problems__handmade_problem(_P_(C6BothBlockSyntaxes));
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 = rout;
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, requires_colon_syntax);
Problems__handmade_problem(_P_(C6NotInOldSyntax));
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;
}
if (uses_colon_syntax)
{
#line 206 "inform7/Chapter 6/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 (Text__indentation_level(rout->word_ref1) != 0)
{
#line 238 "inform7/Chapter 6/Rule Subtrees.w"
current_sentence = rout;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__handmade_problem(_P_(C6NonflushRule));
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 218 "inform7/Chapter 6/Rule Subtrees.w"
;
for (prev = NULL, p = rout->down, k=1; p; prev = p, p = p->next, k++) {
control_structure_phrase *csp =
Parser__Sentences__detect_control_structure(p->word_ref1, p->word_ref2);
{
#line 256 "inform7/Chapter 6/Rule Subtrees.w"
indent = expected_indent;
if (p->word_ref1 >= 0) {
if (Text__indentation_level(p->word_ref1) > 0)
indent = Text__indentation_level(p->word_ref1);
else switch (Text__break_before(p->word_ref1)) {
case '\n': indent = 0; break;
case '\t': indent = 1; break;
default:
if ((prev) && (csp == NULL)) {
control_structure_phrase *pcsp =
Parser__Sentences__detect_control_structure(
prev->word_ref1, prev->word_ref2);
if ((pcsp) && (pcsp->allow_run_on)) break;
}
if (run_on_at == NULL) run_on_at = p; break;
}
if (indent >= GROSS_AMOUNT_OF_INDENTATION)
{
#line 432 "inform7/Chapter 6/Rule Subtrees.w"
indent_overmuch = TRUE;
if (first_overindented_phrase == NULL) first_overindented_phrase = p;
}
#line 272 "inform7/Chapter 6/Rule Subtrees.w"
;
}
}
#line 223 "inform7/Chapter 6/Rule Subtrees.w"
;
{
#line 287 "inform7/Chapter 6/Rule Subtrees.w"
if (indent == 0) {
{
#line 404 "inform7/Chapter 6/Rule Subtrees.w"
indent_misalign = TRUE;
if (first_misaligned_phrase == NULL) first_misaligned_phrase = p;
}
#line 288 "inform7/Chapter 6/Rule Subtrees.w"
;
{
#line 381 "inform7/Chapter 6/Rule Subtrees.w"
if ((blo_sp > 0) &&
(blstack_stage[blo_sp-1] == 0) &&
(blstack_construct[blo_sp-1]->body_empty_except_for_subordinates)) {
{
#line 495 "inform7/Chapter 6/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
current_sentence = rout;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, p);
Problems__handmade_problem(_P_(C6NonCaseInIf));
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 384 "inform7/Chapter 6/Rule Subtrees.w"
;
}
just_opened_block = FALSE;
}
#line 289 "inform7/Chapter 6/Rule Subtrees.w"
;
} else {
if ((csp) && (csp->subordinate_to)) {
{
#line 313 "inform7/Chapter 6/Rule Subtrees.w"
expected_indent--;
if (expected_indent < indent) {
{
#line 510 "inform7/Chapter 6/Rule Subtrees.w"
if ((indent_misalign == FALSE) && (suppress_further_problems == FALSE)) {
current_sentence = p;
if (csp->subordinate_to == if_CSP)
Problems__sentence_problem(_P_(C6MisalignedOtherwise),
"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__sentence_problem(_P_(C6MisalignedCase),
"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 315 "inform7/Chapter 6/Rule Subtrees.w"
;
} else {
{
#line 356 "inform7/Chapter 6/Rule Subtrees.w"
if ((just_opened_block) &&
(blo_sp > 0) &&
(!(blstack_construct[blo_sp-1]->body_empty_except_for_subordinates)) && (p))
{
#line 473 "inform7/Chapter 6/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
LOG("$T\n", rout);
current_sentence = rout;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, prev);
Problems__quote_source_eliding_begin(3, p);
Problems__handmade_problem(_P_(C6EmptyIndentedBlock));
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 359 "inform7/Chapter 6/Rule Subtrees.w"
;
while (indent < expected_indent) {
parse_node *opening;
if (blo_sp == 0) {
{
#line 404 "inform7/Chapter 6/Rule Subtrees.w"
indent_misalign = TRUE;
if (first_misaligned_phrase == NULL) first_misaligned_phrase = p;
}
#line 363 "inform7/Chapter 6/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 393 "inform7/Chapter 6/Rule Subtrees.w"
parse_node *implicit_end = Parser__Nodes__new(COMMAND_NT);
implicit_end->next = prev->next; prev->next = implicit_end;
prev = implicit_end;
implicit_end->word_ref1 = lexer_wordcount;
Text__feed_into_lexer("end ", FALSE, NULL);
Text__splice_words(opening->word_ref1, opening->word_ref1);
implicit_end->word_ref2 = lexer_wordcount - 1;
}
#line 375 "inform7/Chapter 6/Rule Subtrees.w"
;
}
}
#line 317 "inform7/Chapter 6/Rule Subtrees.w"
;
if ((blo_sp == 0) ||
(csp->subordinate_to != blstack_construct[blo_sp-1])) {
{
#line 510 "inform7/Chapter 6/Rule Subtrees.w"
if ((indent_misalign == FALSE) && (suppress_further_problems == FALSE)) {
current_sentence = p;
if (csp->subordinate_to == if_CSP)
Problems__sentence_problem(_P_(C6MisalignedOtherwise),
"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__sentence_problem(_P_(C6MisalignedCase),
"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 320 "inform7/Chapter 6/Rule Subtrees.w"
;
} else {
if (blstack_stage[blo_sp-1] > csp->used_at_stage)
{
#line 532 "inform7/Chapter 6/Rule Subtrees.w"
if ((indent_misalign == FALSE) && (suppress_further_problems == FALSE)) {
current_sentence = p;
Problems__sentence_problem(_P_(C6MisarrangedOtherwise),
"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 323 "inform7/Chapter 6/Rule Subtrees.w"
;
blstack_stage[blo_sp-1] = csp->used_at_stage;
}
}
expected_indent++;
}
#line 292 "inform7/Chapter 6/Rule Subtrees.w"
;
just_opened_block = TRUE;
} else {
if (expected_indent < indent)
{
#line 404 "inform7/Chapter 6/Rule Subtrees.w"
indent_misalign = TRUE;
if (first_misaligned_phrase == NULL) first_misaligned_phrase = p;
}
#line 295 "inform7/Chapter 6/Rule Subtrees.w"
;
if (expected_indent > indent)
{
#line 356 "inform7/Chapter 6/Rule Subtrees.w"
if ((just_opened_block) &&
(blo_sp > 0) &&
(!(blstack_construct[blo_sp-1]->body_empty_except_for_subordinates)) && (p))
{
#line 473 "inform7/Chapter 6/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
LOG("$T\n", rout);
current_sentence = rout;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, prev);
Problems__quote_source_eliding_begin(3, p);
Problems__handmade_problem(_P_(C6EmptyIndentedBlock));
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 359 "inform7/Chapter 6/Rule Subtrees.w"
;
while (indent < expected_indent) {
parse_node *opening;
if (blo_sp == 0) {
{
#line 404 "inform7/Chapter 6/Rule Subtrees.w"
indent_misalign = TRUE;
if (first_misaligned_phrase == NULL) first_misaligned_phrase = p;
}
#line 363 "inform7/Chapter 6/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 393 "inform7/Chapter 6/Rule Subtrees.w"
parse_node *implicit_end = Parser__Nodes__new(COMMAND_NT);
implicit_end->next = prev->next; prev->next = implicit_end;
prev = implicit_end;
implicit_end->word_ref1 = lexer_wordcount;
Text__feed_into_lexer("end ", FALSE, NULL);
Text__splice_words(opening->word_ref1, opening->word_ref1);
implicit_end->word_ref2 = lexer_wordcount - 1;
}
#line 375 "inform7/Chapter 6/Rule Subtrees.w"
;
}
}
#line 297 "inform7/Chapter 6/Rule Subtrees.w"
;
expected_indent = indent;
{
#line 381 "inform7/Chapter 6/Rule Subtrees.w"
if ((blo_sp > 0) &&
(blstack_stage[blo_sp-1] == 0) &&
(blstack_construct[blo_sp-1]->body_empty_except_for_subordinates)) {
{
#line 495 "inform7/Chapter 6/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
current_sentence = rout;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, p);
Problems__handmade_problem(_P_(C6NonCaseInIf));
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 384 "inform7/Chapter 6/Rule Subtrees.w"
;
}
just_opened_block = FALSE;
}
#line 299 "inform7/Chapter 6/Rule Subtrees.w"
;
}
}
if (expected_indent < 1) expected_indent = 1;
}
#line 224 "inform7/Chapter 6/Rule Subtrees.w"
;
{
#line 339 "inform7/Chapter 6/Rule Subtrees.w"
if ((csp) && (csp->subordinate_to == NULL) && (Parser__Nodes__int_annotation(p, colon_block_command_ANNOT))) {
p->word_ref2++;
Text__Vocabulary__change_text_of_word(p->word_ref2, "begin");
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 225 "inform7/Chapter 6/Rule Subtrees.w"
;
}
indent = 1;
{
#line 356 "inform7/Chapter 6/Rule Subtrees.w"
if ((just_opened_block) &&
(blo_sp > 0) &&
(!(blstack_construct[blo_sp-1]->body_empty_except_for_subordinates)) && (p))
{
#line 473 "inform7/Chapter 6/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
LOG("$T\n", rout);
current_sentence = rout;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, prev);
Problems__quote_source_eliding_begin(3, p);
Problems__handmade_problem(_P_(C6EmptyIndentedBlock));
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 359 "inform7/Chapter 6/Rule Subtrees.w"
;
while (indent < expected_indent) {
parse_node *opening;
if (blo_sp == 0) {
{
#line 404 "inform7/Chapter 6/Rule Subtrees.w"
indent_misalign = TRUE;
if (first_misaligned_phrase == NULL) first_misaligned_phrase = p;
}
#line 363 "inform7/Chapter 6/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 393 "inform7/Chapter 6/Rule Subtrees.w"
parse_node *implicit_end = Parser__Nodes__new(COMMAND_NT);
implicit_end->next = prev->next; prev->next = implicit_end;
prev = implicit_end;
implicit_end->word_ref1 = lexer_wordcount;
Text__feed_into_lexer("end ", FALSE, NULL);
Text__splice_words(opening->word_ref1, opening->word_ref1);
implicit_end->word_ref2 = lexer_wordcount - 1;
}
#line 375 "inform7/Chapter 6/Rule Subtrees.w"
;
}
}
#line 229 "inform7/Chapter 6/Rule Subtrees.w"
;
if (indent_overmuch)
{
#line 438 "inform7/Chapter 6/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
current_sentence = rout;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, first_overindented_phrase);
Problems__handmade_problem(_P_(C6TooMuchIndentation));
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 231 "inform7/Chapter 6/Rule Subtrees.w"
else if (run_on_at)
{
#line 454 "inform7/Chapter 6/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
current_sentence = rout;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, run_on_at);
Problems__handmade_problem(_P_(C6RunOnsInTabbedRoutine));
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 232 "inform7/Chapter 6/Rule Subtrees.w"
else if (indent_misalign)
{
#line 410 "inform7/Chapter 6/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
current_sentence = rout;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, first_misaligned_phrase);
Problems__handmade_problem(_P_(C6MisalignedIndentation));
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__diagnose_further();
Problems__issue_problem_end();
}
}
#line 233 "inform7/Chapter 6/Rule Subtrees.w"
;
}
#line 154 "inform7/Chapter 6/Rule Subtrees.w"
;
}
#line 548 "inform7/Chapter 6/Rule Subtrees.w"
control_structure_phrase *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;
return csp;
}
void Parser__Sentences__create_standard_csps(void) {
switch_CSP = csp_new();
switch_CSP->body_empty_except_for_subordinates = TRUE;
switch_CSP->indent_subblocks = TRUE;
switch_CSP->requires_new_syntax = TRUE;
if_CSP = csp_new();
repeat_CSP = csp_new();
while_CSP = csp_new();
otherwise_CSP = csp_new();
otherwise_CSP->subordinate_to = if_CSP;
otherwise_CSP->used_at_stage = 1;
otherwise_if_CSP = csp_new();
otherwise_if_CSP->subordinate_to = if_CSP;
otherwise_if_CSP->used_at_stage = 0;
case_CSP = 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 = 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;
lambda_CSP = csp_new();
lambda_CSP->requires_new_syntax = TRUE;
}
int Parser__Sentences__is_otherwise_if(int w1, int w2) {
if (Parser__Sentences__detect_control_structure(w1, w2) == otherwise_if_CSP) return TRUE;
return FALSE;
}
control_structure_phrase *Parser__Sentences__detect_control_structure(int w1, int w2) {
if (parse_nt_against_word_range(control_structure_phrase_NTM, w1, w2, NULL, NULL)) return most_recent_result_p;
return NULL;
}
#line 616 "inform7/Chapter 6/Rule Subtrees.w"
int control_structure_phrase_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = default_case_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = 0; *XP = case_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *X = 0; *XP = lambda_CSP /* a speculative lambda syntax, not yet used */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 627 "inform7/Chapter 6/Rule Subtrees.w"
int end_control_structure_phrase_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 632 "inform7/Chapter 6/Rule Subtrees.w"
#line 636 "inform7/Chapter 6/Rule Subtrees.w"
int phrase_beginning_block_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 638 "inform7/Chapter 6/Rule Subtrees.w"
#line 104 "inform7/Chapter 6/Verify Parse Tree.w"
parse_tree_node_type parse_tree_node_types[HIGHEST_NODE_TYPE+1] = {
/* the columns are: name, max and min children, weight, required parent (if any), whether allowed in assertions */
{ "(zero node type)", 0, INFTY, 0, -1, FALSE },
{ "ROOT_NT", 0, INFTY, 1, -1, FALSE },
{ "BIBLIOGRAPHIC_NT", 0, 0, 2, ROOT_NT, FALSE },
{ "HEADING_NT", 0, 0, 2, ROOT_NT, FALSE },
{ "INCLUDE_NT", 0, 0, 2, ROOT_NT, FALSE },
{ "BEGINHERE_NT", 0, 0, 2, ROOT_NT, FALSE },
{ "ENDHERE_NT", 0, 0, 2, ROOT_NT, FALSE },
{ "SENTENCE_NT", 0, INFTY, 2, ROOT_NT, FALSE },
{ "ROUTINE_NT", 0, INFTY, 2, ROOT_NT, FALSE },
{ "INFORM6CODE_NT", 0, 0, 2, ROOT_NT, FALSE },
{ "TABLE_NT", 0, 0, 2, ROOT_NT, FALSE },
{ "EQUATION_NT", 0, 0, 2, ROOT_NT, FALSE },
{ "TRACE_NT", 0, 0, 2, ROOT_NT, FALSE },
{ "RELATIONSHIP_NT", 0, 2, -3, -1, TRUE },
{ "CALLED_NT", 2, 2, 4, -1, FALSE },
{ "WITH_NT", 2, 2, 5, -1, TRUE },
{ "AND_NT", 2, 2, 6, -1, TRUE },
{ "KIND_NT", 0, 1, 7, -1, TRUE },
{ "X_OF_Y_NT", 2, 2, 7, -1, TRUE },
{ "VERB_NT", 0, 0, 10, SENTENCE_NT, FALSE },
{ "CREATED_NT", 0, 0, 10, -1, TRUE },
{ "PROPER_NOUN_NT", 0, 0, 10, -1, TRUE },
{ "PROPERTY_LIST_NT", 0, 0, 10, -1, TRUE },
{ "FROM_NT", 2, 2, 0, -1, FALSE },
{ "COMMAND_NT", 0, 0, 10, ROUTINE_NT, FALSE },
{ "ALLOWED_NT", 1, 1, 0, SENTENCE_NT, TRUE },
{ "EVERY_NT", 0, INFTY, 0, -1, TRUE },
{ "COMMON_NOUN_NT", 0, INFTY, 0, -1, TRUE },
{ "ACTION_NT", 0, INFTY, 0, -1, TRUE },
{ "ADJECTIVE_NT", 0, INFTY, 0, -1, TRUE },
{ "PROPERTYCALLED_NT", 2, 2, 4, -1, FALSE },
{ "TOKEN_NT", 0, INFTY, 0, -1, FALSE }
};
#line 152 "inform7/Chapter 6/Verify Parse Tree.w"
void Parser__Nodes__Types__log(int t) {
if ((t<1) || (t>HIGHEST_NODE_TYPE)) LOG("?%d_NT", t);
else LOG("%s", parse_tree_node_types[t].node_type_name);
}
char *Parser__Nodes__Types__get_name(int t) {
return parse_tree_node_types[t].node_type_name;
}
#line 173 "inform7/Chapter 6/Verify Parse Tree.w"
int tree_stats_size = 0, tree_stats_depth = 0, tree_stats_width = 0;
void Parser__Nodes__verify_integrity(parse_node *p, int worth_logging) {
tree_stats_size = 0; tree_stats_depth = 0; tree_stats_width = 1;
verify_tree_integrity_recursively(p->down, p, "down", 0);
tidy_tree_after_verification(p->down);
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 198 "inform7/Chapter 6/Verify Parse Tree.w"
void tidy_tree_after_verification(parse_node *p) {
for (; p; p = p->next) {
int t = Parser__Nodes__type(p);
if (MARKED_WITH_CROSS(t))
Parser__Nodes__set_node_type(p, t - OUTRAGEOUSLY_LARGE_NODE_TYPE);
if (p->down) tidy_tree_after_verification(p->down);
}
}
#line 212 "inform7/Chapter 6/Verify Parse Tree.w"
void verify_tree_integrity_recursively(parse_node *p, parse_node *from, char *way,
int depth) {
int t, 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");
}
t = Parser__Nodes__type(p);
if (MARKED_WITH_CROSS(t)) {
LOG("Cycle found in parse tree, found %s from:\n$P", way, from);
internal_error_tree_unsafe("Cycle found in parse tree");
}
if ((t >= 1) && (t < HIGHEST_NODE_TYPE)) {
Parser__Nodes__set_node_type(p, t + OUTRAGEOUSLY_LARGE_NODE_TYPE);
tree_stats_size++;
} else {
LOG("Invalid node type (%d) found %s from:\n$P", t, from);
internal_error_tree_unsafe("Link broken in parse tree");
}
if (p->down) verify_tree_integrity_recursively(p->down, p, "down", depth);
}
if (width > tree_stats_width) tree_stats_width = width;
}
#line 248 "inform7/Chapter 6/Verify Parse Tree.w"
int node_errors = 0;
void Parser__Nodes__verify(void) {
LOGIF(VERIFICATIONS, "[Verifying initial parse tree]\n");
if (tree_root == NULL) internal_error_tree_unsafe("Root of parse tree NULL");
if (tree_root->down) Parser__Nodes__verify_integrity(tree_root, TRUE);
node_errors = 0;
verify_initial_parse_tree_invariant(tree_root, NULL, 1);
if (node_errors > 0) {
LOG("[Verification failed: %d node errors]\n", node_errors);
internal_error_tree_unsafe("The initial parse tree is broken");
}
LOGIF(VERIFICATIONS, "[Initial parse tree correct.]\n");
}
#line 269 "inform7/Chapter 6/Verify Parse Tree.w"
void verify_initial_parse_tree_invariant(parse_node *p, parse_node *parent, int current_weight) {
parse_node *q;
int t = Parser__Nodes__type(p), children_count = 0;
int weight_here = parse_tree_node_types[t].node_weight;
{
#line 288 "inform7/Chapter 6/Verify Parse Tree.w"
if (weight_here == 0) {
LOG("N%d is %s, which is not allowed in initial tree\n",
p->allocation_id, parse_tree_node_types[t].node_type_name);
LOG("$P", p);
node_errors++;
}
}
#line 274 "inform7/Chapter 6/Verify Parse Tree.w"
;
{
#line 299 "inform7/Chapter 6/Verify Parse Tree.w"
if ((parent) && (weight_here > 0) && (weight_here < current_weight)) {
LOG("N%d is %s (weight %d): should not be a child of %s (weight %d)\n",
p->allocation_id,
parse_tree_node_types[t].node_type_name,
parse_tree_node_types[t].node_weight,
parse_tree_node_types[Parser__Nodes__type(parent)].node_type_name,
current_weight);
node_errors++;
if (parent == tree_root) LOG("$P", p); else LOG("$P", parent);
}
}
#line 275 "inform7/Chapter 6/Verify Parse Tree.w"
;
{
#line 313 "inform7/Chapter 6/Verify Parse Tree.w"
if (parent) {
int t_parent = parse_tree_node_types[t].required_parent_node_type;
if ((t_parent != -1) && (t_parent != Parser__Nodes__type(parent))) {
LOG("N%d is a %s with parent %s not %s\n",
p->allocation_id,
parse_tree_node_types[t].node_type_name,
parse_tree_node_types[Parser__Nodes__type(parent)].node_type_name,
parse_tree_node_types[t_parent].node_type_name);
if (parent == tree_root) LOG("$P", p); else LOG("$P", parent);
node_errors++;
}
}
}
#line 276 "inform7/Chapter 6/Verify Parse Tree.w"
;
if (weight_here < 0) weight_here = -weight_here;
for (q=p->down; q; q=q->next, children_count++)
verify_initial_parse_tree_invariant(q, p, weight_here);
{
#line 329 "inform7/Chapter 6/Verify Parse Tree.w"
if (children_count < parse_tree_node_types[t].min_children) {
LOG("N%d has %d children, but min for %s is %d:\n",
p->allocation_id,
children_count, parse_tree_node_types[t].node_type_name,
parse_tree_node_types[t].min_children);
Parser__Nodes__log_subtree(p, 1);
node_errors++;
}
if (children_count > parse_tree_node_types[t].max_children) {
LOG("N%d has %d children, but max for %s is %d:\n",
p->allocation_id,
children_count, parse_tree_node_types[t].node_type_name,
parse_tree_node_types[t].max_children);
Parser__Nodes__log_subtree(p, 1);
node_errors++;
}
}
#line 282 "inform7/Chapter 6/Verify Parse Tree.w"
;
}
#line 355 "inform7/Chapter 6/Verify Parse Tree.w"
int Parser__Nodes__Types__allow_in_assertions(parse_node *subtree) {
int t;
Parser__Nodes__verify_integrity(subtree, FALSE);
t = Parser__Nodes__type(subtree);
if (parse_tree_node_types[t].allow_in_assertions) return TRUE;
return FALSE;
}
#line 190 "inform7/Chapter 7/Extension Files.w"
extension_file *Extensions__Files__new(int author_w1, int author_w2,
int nw1, int nw2, int vm1, int vm2, int version_word) {
char violation[160]; /* enough for two lines of type */
violation[0] = 0;
extension_file *ef = CREATE(extension_file);
ef->author_w1 = author_w1; ef->author_w2 = author_w2;
ef->name_w1 = nw1; ef->name_w2 = nw2;
{
#line 219 "inform7/Chapter 7/Extension Files.w"
char exft[MAX_FILENAME_LENGTH], exfa[MAX_FILENAME_LENGTH];
Text__print_raw_text_to_string_truncated(ef->author_w1, ef->author_w2, exfa, MAX_FILENAME_LENGTH);
Text__print_raw_text_to_string_truncated(ef->name_w1, ef->name_w2, exft, MAX_FILENAME_LENGTH);
if (Extensions__Census__currently_recording_errors() == FALSE) {
if (Platform__strlen(exfa) >= MAX_EXTENSION_AUTHOR_LENGTH) /* |intest| cannot easily test this */
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));
if (Platform__strlen(exft) >= MAX_EXTENSION_AUTHOR_LENGTH) /* |intest| cannot easily test this */
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));
}
Extensions__IDs__new(&(ef->ef_id), exfa, exft, LOADED_EIDBC);
if (Extensions__IDs__is_standard_rules(&(ef->ef_id))) standard_rules_extension = ef;
}
#line 197 "inform7/Chapter 7/Extension Files.w"
;
ef->min_version_needed = version_word;
ef->inclusion_sentence = current_sentence;
ef->VM_restriction_w1 = vm1; ef->VM_restriction_w2 = vm2;
ef->body_w1 = -1; ef->body_w2 = -1;
ef->body_text_unbroken = FALSE;
ef->doc_w1 = -1; ef->doc_w2 = -1;
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__extension_problem(_P_(Untestable), ef, violation); /* see below */
return ef;
}
#line 252 "inform7/Chapter 7/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 7/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 7/Extension Files.w"
extension_identifier *Extensions__Files__get_eid(extension_file *ef) {
return &(ef->ef_id);
}
#line 285 "inform7/Chapter 7/Extension Files.w"
int Extensions__Files__get_version_wn(extension_file *ef) {
return ef->version_loaded;
}
#line 295 "inform7/Chapter 7/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 7/Extension Files.w"
void Extensions__Files__write_name_to_file(extension_file *ef, OUTPUT_STREAM) {
Text__print_raw_text_to_stream(ef->name_w1, ef->name_w2, OUT);
}
void Extensions__Files__write_author_to_file(extension_file *ef, OUTPUT_STREAM) {
Text__print_raw_text_to_stream(ef->author_w1, ef->author_w2, OUT);
}
#line 316 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__log(extension_file *ef) {
if (ef == NULL) { LOG("<null-extension-file>"); return; }
LOG("$W by $W", ef->name_w1, ef->name_w2, ef->author_w1, ef->author_w2);
}
#line 325 "inform7/Chapter 7/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 \"");
Text__print_raw_text_within_i6_literal(OUT, ef->name_w1, ef->name_w2);
WRITE("\" by ");
Text__print_raw_text_within_i6_literal(OUT, ef->author_w1, ef->author_w2);
WRITE("\n");
}
}
#line 340 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__write_full_title_to_stream(OUTPUT_STREAM, extension_file *ef) {
Text__print_raw_text_to_stream(ef->name_w1, ef->name_w2, OUT);
WRITE(" by ");
Text__print_raw_text_to_stream(ef->author_w1, ef->author_w2, OUT);
}
#line 357 "inform7/Chapter 7/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_words(3, ef->version_loaded, ef->version_loaded);
Problems__handmade_problem(_P_(C7ExtVersionTooLow));
Problems__issue_problem_segment(
"You wrote %1: but my copy of %2 is only version %3.");
Problems__issue_problem_end();
} else {
Problems__handmade_problem(_P_(C7ExtNoVersion));
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 7/Extension Files.w"
void Extensions__Files__ShowExtensionVersions_routine(OUTPUT_STREAM) {
OUT = Code__Routines__begin(OUT, "ShowExtensionVersions");
extension_file *ef;
LOOP_OVER(ef, extension_file) {
char the_author_name[512];
Text__print_raw_text_to_string(ef->author_w1, ef->author_w2, the_author_name);
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... */
(Plugins__Bibliographic__story_author_is(the_author_name) == FALSE))) /* ...didn't write this extension */
credit_ef(OUT, ef, TRUE); /* then we award a credit */
}
OUT = Code__Routines__end(OUT);
OUT = Code__Routines__begin(OUT, "ShowFullExtensionVersions");
LOOP_OVER(ef, extension_file) credit_ef(OUT, ef, TRUE);
OUT = Code__Routines__end(OUT);
OUT = Code__Routines__begin(OUT, "ShowOneExtension");
Code__LocalVariables__add_named_call("id");
LOOP_OVER(ef, extension_file) {
WRITE("if (id == %d) ", ef->allocation_id + 1);
credit_ef(OUT, ef, FALSE);
}
OUT = Code__Routines__end(OUT);
}
#line 435 "inform7/Chapter 7/Extension Files.w"
void 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 ");
Text__print_raw_text_to_stream(ef->version_loaded, ef->version_loaded, OUT);
}
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 7/Extension Files.w"
void Extensions__Files__index(void) {
INDEX("<p>EXTENSIONS</p>\n");
index_extensions_from(NULL);
extension_file *from;
LOOP_OVER(from, extension_file)
if (from != standard_rules_extension)
index_extensions_from(from);
index_extensions_from(standard_rules_extension);
INDEX("<p></p>");
}
void 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 (ef->inclusion_sentence->word_ref1 >= 0) {
source_location sl = Text__word_location(ef->inclusion_sentence->word_ref1);
if (sl.file_of_origin == NULL) owner = standard_rules_extension;
else owner = Text__Reader__sf_get_extension_corresponding(
Text__file_of_origin(ef->inclusion_sentence->word_ref1));
}
if (owner != from) continue;
if (show_head) {
Formats__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 ");
Text__print_raw_text_to_stream(from->name_w1, from->name_w2, ifl);
}
show_head = FALSE;
INDEX("</font></p>");
}
INDEX("<ul class=\"leaders\"><li class=\"leaded indent2\"><span>");
Text__print_raw_text_to_stream(ef->name_w1, ef->name_w2, ifl);
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 ");
Text__print_raw_text_to_stream(ef->author_w1, ef->author_w2, ifl);
}
if (ef->version_loaded >= 0) {
INDEX(" <small>version ");
Text__print_raw_text_to_stream(ef->version_loaded, ef->version_loaded, ifl);
INDEX("</small>");
}
if (ef->extra_credit_as_lexed[0]) {
INDEX(" <small>(");
Text__print_literal_string_to_file(ifl, ef->extra_credit_as_lexed);
INDEX(")</small>");
}
INDEX("</span><span>");
INDEX("%d words", Text__Reader__sf_total_word_count(ef->read_into_file));
if (from == NULL) Index__link(ef->inclusion_sentence->word_ref1);
INDEX("</span></li></ul>\n");
}
}
#line 527 "inform7/Chapter 7/Extension Files.w"
void Extensions__Files__handle_census_mode(void) {
if (census_mode) {
Extensions__Dictionary__load();
Extensions__Census__perform();
write_top_level_of_extensions_documentation();
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();
write_top_level_of_extensions_documentation();
LOOP_OVER(ef, extension_file) Extensions__Documentation__write_detailed(ef);
write_sketchy_documentation_for_extensions_found();
Extensions__Dictionary__write_back();
if (Log__Aspects__on(EXTENSIONS_CENSUS_DA)) Extensions__IDs__log_EID_hash_table();
}
#line 553 "inform7/Chapter 7/Extension Files.w"
void write_sketchy_documentation_for_extensions_found(void) {
extension_census_datum *ecd;
LOOP_OVER(ecd, extension_census_datum)
Extensions__Documentation__write_sketchy(ecd);
}
#line 589 "inform7/Chapter 7/Extension Files.w"
void write_top_level_of_extensions_documentation(void) {
write_top_level_extensions_page("Extensions", 1);
write_top_level_extensions_page("ExtIndex", 2);
}
#line 597 "inform7/Chapter 7/Extension Files.w"
void write_top_level_extensions_page(char *leafname, int content) {
STREAM HOMEPAGE_struct;
STREAM *HOMEPAGE = &HOMEPAGE_struct;
FILE *TEMPLATE;
char path_to_census[MAX_FILENAME_LENGTH];
char path_to_model[MAX_FILENAME_LENGTH];
sprintf(path_to_census, "%s%c%s.html", pathname_of_extension_docs, FOLDER_SEPARATOR,
leafname);
if (STREAM_OPEN_TO_FILE(HOMEPAGE, path_to_census, UTF8_ENC) == FALSE)
Problems__Fatal__issue2("Unable to open extensions documentation index for writing",
path_to_census);
sprintf(path_to_model, "%s%cReserved%c%s",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR,
EXTENSIONS_MODEL_HTML);
TEMPLATE = Platform__iso_fopen(path_to_model, "r");
if (TEMPLATE == NULL)
Problems__Fatal__issue("Unable to open model extensions documentation for reading");
{
#line 628 "inform7/Chapter 7/Extension Files.w"
char line_of_template[LONGEST_LINE_IN_EX_TEMPLATE];
int skipping_between_markers = FALSE;
while (!(feof(TEMPLATE))) {
int n = Files__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) {
Formats__HTML__begin_html_table(HOMEPAGE, NULL, TRUE, 0, 4, 0, 0, 0);
Formats__HTML__first_html_column(HOMEPAGE, 0);
STREAM_WRITE(HOMEPAGE, "<img src='inform:/doc_images/extensions@2x.png' border=0 width=150 height=150>");
Formats__HTML__next_html_column(HOMEPAGE, 0);
STREAM_WRITE(HOMEPAGE, "<div class='headingbox'>\n");
STREAM_WRITE(HOMEPAGE, "<div class='headingtext'>Installed Extensions</div>\n");
STREAM_WRITE(HOMEPAGE, "<div class='headingrubric'>Bundles of extra rules or phrases "
"to extend what Inform can do</div>\n");
STREAM_WRITE(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) STREAM_WRITE(HOMEPAGE, "%s", line_of_template);
if (strcmp(line_of_template, LINE_MARKING_END_OF_CENSUS) == 0)
skipping_between_markers = FALSE;
}
}
#line 614 "inform7/Chapter 7/Extension Files.w"
;
STREAM_CLOSE(HOMEPAGE);
fclose(TEMPLATE);
}
#line 31 "inform7/Chapter 7/Including Extensions.w"
void Extensions__Inclusion__traverse(void) {
int includes_cleared;
do {
parse_node *pn, *elder;
includes_cleared = TRUE;
if (problem_count > 0) return;
for (elder=NULL, TREE_START(pn); pn; TREE_NEXT(pn)) {
current_sentence = pn; /* to report problems at the right place */
if (Parser__Nodes__type(pn) == INCLUDE_NT) {
{
#line 59 "inform7/Chapter 7/Including Extensions.w"
if (elder == NULL) tree_root->down = NULL; else elder->next = NULL; /* trim off pn and the tail */
current_sentence = pn; /* in case of problem messages */
fulfill_request_to_include_extension(pn->down, pn->down->next); /* which may add new nodes */
if (pn->next) elder = Parser__Nodes__graft(pn->next, tree_root); /* put the tail (not pn) back after the new nodes */
}
#line 40 "inform7/Chapter 7/Including Extensions.w"
;
includes_cleared = FALSE;
continue;
}
elder = pn;
}
} while (includes_cleared == FALSE);
}
#line 77 "inform7/Chapter 7/Including Extensions.w"
int extension_title_and_version_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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
default: *X = R[0]; break;
}
return TRUE;
}
#line 81 "inform7/Chapter 7/Including Extensions.w"
int extension_unversioned_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; rest1_NTMV = extension_unversioned_NTM->range_result_w1[1]; rest2_NTMV = extension_unversioned_NTM->range_result_w2[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 85 "inform7/Chapter 7/Including Extensions.w"
int extension_unversioned_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 93 "inform7/Chapter 7/Including Extensions.w"
t1_NTMV = -1; t2_NTMV = -1;
Problems__sentence_problem(_P_(C7IncludeExtQuoted),
"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 87 "inform7/Chapter 7/Including Extensions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; t1_NTMV = w1; t2_NTMV = w2;
#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 7/Including Extensions.w"
#line 103 "inform7/Chapter 7/Including Extensions.w"
int extension_version_NTMR(int w1, int w2, int *X, void **XP) {
#line 104 "inform7/Chapter 7/Including Extensions.w"
*X = w1; /* actually, defer parsing by returning a word number here */
return TRUE;
}
#line 111 "inform7/Chapter 7/Including Extensions.w"
void fulfill_request_to_include_extension(parse_node *p, parse_node *auth_p) {
if (Parser__Nodes__type(p) == AND_NT) {
fulfill_request_to_include_extension(p->down, auth_p);
fulfill_request_to_include_extension(p->down->next, auth_p);
return;
}
int w1 = p->word_ref1, w2 = p->word_ref2;
rest1_NTMV = -1; rest2_NTMV = -1;
t1_NTMV = -1; t2_NTMV = -1;
parse_nt_against_word_range(extension_title_and_version_NTM, w1, w2, NULL, NULL);
w1 = t1_NTMV; w2 = t2_NTMV;
int aw1 = auth_p->word_ref1, aw2 = auth_p->word_ref2;
int rest1 = rest1_NTMV, rest2 = rest2_NTMV;
int version_word = most_recent_result;
if (w1 >= 0)
{
#line 139 "inform7/Chapter 7/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(aw1, aw2, w1, w2, version_word, rest1, rest2);
if (requested_extension->body_text_unbroken) {
Parser__Sentences__break(requested_extension->body_w1, requested_extension->body_w2,
requested_extension, NULL);
requested_extension->body_text_unbroken = FALSE;
}
}
#line 127 "inform7/Chapter 7/Including Extensions.w"
;
}
#line 155 "inform7/Chapter 7/Including Extensions.w"
extension_file *Extensions__Inclusion__load(int author_w1, int author_w2,
int name_w1, int name_w2, int version_word, int vm1, int vm2) {
extension_file *ef;
LOOP_OVER(ef, extension_file)
if ((Text__compare_word_range(ef->author_w1, ef->author_w2, author_w1, author_w2))
&& (Text__compare_word_range(ef->name_w1, ef->name_w2, name_w1, name_w2)))
{
#line 182 "inform7/Chapter 7/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 161 "inform7/Chapter 7/Including Extensions.w"
;
ef = Extensions__Files__new(author_w1, author_w2, name_w1, name_w2, vm1, vm2, version_word);
{
#line 193 "inform7/Chapter 7/Including Extensions.w"
char partial_pathname[MAX_FILENAME_LENGTH];
char synopsis[MAX_FILENAME_LENGTH];
int start_wn, end_wn;
{
#line 228 "inform7/Chapter 7/Including Extensions.w"
int i;
Text__print_text_to_string(author_w1, author_w2, partial_pathname);
sprintf(partial_pathname+Platform__strlen(partial_pathname), "%c", FOLDER_SEPARATOR);
Text__print_text_to_string(name_w1, name_w2, partial_pathname+Platform__strlen(partial_pathname));
Text__print_raw_text_to_string(name_w1, name_w2, synopsis);
sprintf(synopsis+Platform__strlen(synopsis), " by ");
Text__print_raw_text_to_string(author_w1, author_w2, synopsis+Platform__strlen(synopsis));
for (i=0; synopsis[i]; i++) synopsis[i] =
(char) (Formats__HTML__iso_remove_accents((int) synopsis[i]));
}
#line 197 "inform7/Chapter 7/Including Extensions.w"
;
start_wn = lexer_wordcount;
switch (Text__Reader__read_extension_source_text(ef, partial_pathname, 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;
}
end_wn = lexer_wordcount-1;
if (end_wn >= start_wn)
{
#line 258 "inform7/Chapter 7/Including Extensions.w"
parse_nt_against_word_range(extension_body_NTM, start_wn, end_wn, NULL, NULL);
GET_RW(extension_body_NTM, 1, (ef->body_w1), (ef->body_w2));
if (most_recent_result) GET_RW(extension_body_NTM, 2, (ef->doc_w1), (ef->doc_w2));
ef->body_text_unbroken = TRUE; /* mark this to be sentence-broken */
}
#line 210 "inform7/Chapter 7/Including Extensions.w"
;
}
#line 165 "inform7/Chapter 7/Including Extensions.w"
;
return ef;
}
#line 251 "inform7/Chapter 7/Including Extensions.w"
int extension_body_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 254 "inform7/Chapter 7/Including Extensions.w"
#line 299 "inform7/Chapter 7/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 = Text__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 334 "inform7/Chapter 7/Including Extensions.w"
LOG("Offending word number %d <%s>\n", vwn, Text__word_text(vwn));
Problems__sentence_problem(_P_(C7ExtVersionMalformed),
"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.)");
Text__Vocabulary__change_text_of_word(vwn, "1");
return 1000000; /* which equates to |1/000000| */
}
#line 325 "inform7/Chapter 7/Including Extensions.w"
;
}
#line 367 "inform7/Chapter 7/Including Extensions.w"
int begins_here_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = R[1]; auth1_NTMV = begins_here_sentence_subject_NTM->range_result_w1[1]; auth2_NTMV = begins_here_sentence_subject_NTM->range_result_w2[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 374 "inform7/Chapter 7/Including Extensions.w"
auth1_NTMV = -1; auth2_NTMV = -1;
Problems__handmade_problem(_P_(C7ExtMiswordedBeginsHere));
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 369 "inform7/Chapter 7/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 370 "inform7/Chapter 7/Including Extensions.w"
#line 387 "inform7/Chapter 7/Including Extensions.w"
void Extensions__Inclusion__check_begins_here(parse_node *PN, extension_file *ef) {
int w1, w2, aw1, aw2;
current_sentence = PN; /* in case problem messages need to be issued */
Problems__quote_extension(1, ef);
Problems__quote_words(2, PN->word_ref1, PN->word_ref2);
w1 = PN->word_ref1; w2 = PN->word_ref2;
parse_nt_against_word_range(begins_here_sentence_subject_NTM, w1, w2, NULL, NULL);
w1 = t1_NTMV; w2 = t2_NTMV; aw1 = auth1_NTMV; aw2 = auth2_NTMV;
if (aw1 < 0) return;
ef->version_loaded = most_recent_result;
ef->VM_restriction_w1 = rest1_NTMV; ef->VM_restriction_w2 = rest2_NTMV;
if (ef->version_loaded >= 0) Extensions__Inclusion__parse_version(ef->version_loaded);
if (ef->VM_restriction_w1 >= 0)
{
#line 416 "inform7/Chapter 7/Including Extensions.w"
if (parse_nt_against_word_range(platform_qualifier_NTM, ef->VM_restriction_w1, ef->VM_restriction_w2, NULL, NULL)) {
if (most_recent_result == PLATFORM_UNMET_HQ)
{
#line 460 "inform7/Chapter 7/Including Extensions.w"
current_sentence = ef->inclusion_sentence;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, ef->name_w1, ef->name_w2);
Problems__quote_words(3, ef->author_w1, ef->author_w2);
Problems__quote_words(4, ef->VM_restriction_w1, ef->VM_restriction_w2);
Problems__handmade_problem(_P_(C7ExtInadequateVM));
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 418 "inform7/Chapter 7/Including Extensions.w"
;
} else {
{
#line 444 "inform7/Chapter 7/Including Extensions.w"
Problems__quote_extension(1, ef);
Problems__quote_words(2, ef->VM_restriction_w1, ef->VM_restriction_w2);
Problems__handmade_problem(_P_(C7ExtMalformedVM));
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 420 "inform7/Chapter 7/Including Extensions.w"
;
}
}
#line 404 "inform7/Chapter 7/Including Extensions.w"
;
if ((Text__compare_word_range(ef->name_w1, ef->name_w2, w1, w2) == FALSE) ||
(Text__compare_word_range(ef->author_w1, ef->author_w2, aw1, aw2) == FALSE))
{
#line 430 "inform7/Chapter 7/Including Extensions.w"
Problems__quote_extension(1, ef);
Problems__quote_words(2, PN->word_ref1, PN->word_ref2);
Problems__handmade_problem(_P_(C7ExtMisidentified));
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 408 "inform7/Chapter 7/Including Extensions.w"
;
}
#line 481 "inform7/Chapter 7/Including Extensions.w"
void Extensions__Inclusion__check_ends_here(parse_node *PN, extension_file *ef) {
int w1, w2;
w1 = PN->word_ref1; w2 = PN->word_ref2;
Text__Languages__remove_the(&w1, &w2);
if ((problem_count == 0) &&
(Text__compare_word_range(ef->name_w1, ef->name_w2, w1, w2) == FALSE)) {
current_sentence = PN;
Problems__quote_extension(1, ef);
Problems__quote_words(2, PN->word_ref1, PN->word_ref2);
Problems__handmade_problem(_P_(C7ExtMisidentifiedEnds));
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 516 "inform7/Chapter 7/Including Extensions.w"
sentence_handler BEGINHERE_SH_handler =
{ BEGINHERE_NT, -1, 0, handle_extension_begins };
sentence_handler ENDHERE_SH_handler =
{ ENDHERE_NT, -1, 0, handle_extension_ends };
void handle_extension_begins(parse_node *PN) {
Problems__empty_headings(0); Parser__Assertions__new_discussion(); near_start_of_extension = 1;
}
void handle_extension_ends(parse_node *PN) {
Problems__empty_headings(0); near_start_of_extension = 0;
}
#line 80 "inform7/Chapter 7/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;
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__print_literal_string_to_file(OUT, eid->raw_title);
if (fancy) WRITE("<font color=\"#404040\">");
WRITE(" by ");
if (fancy) WRITE("</font>");
Text__print_literal_string_to_file(OUT, eid->raw_author_name);
}
void Extensions__IDs__write_to_I6_file(OUTPUT_STREAM, extension_identifier *eid) {
Text__print_literal_string_to_file(OUT, eid->raw_title);
if (Extensions__IDs__is_standard_rules(eid) == FALSE) {
WRITE(" by ");
Text__print_literal_string_to_file(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__print_literal_string_to_file(OUT, eid->author_name);
WRITE("/");
Text__print_literal_string_to_file(OUT, eid->title);
WRITE(".html' STYLE=\"text-decoration: none\"><font color=\"#404040\">");
if (Extensions__IDs__is_standard_rules(eid)) Text__print_literal_string_to_file(OUT, eid->title);
else Extensions__IDs__write_to_HTML_file(OUT, eid, FALSE);
WRITE("</font></a>");
}
#line 149 "inform7/Chapter 7/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 160 "inform7/Chapter 7/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(get_sort_date(eid2), 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(get_sort_word_count(eid2), 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 201 "inform7/Chapter 7/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 227 "inform7/Chapter 7/Extension Identifiers.w"
int EID_database_created = FALSE;
extension_identifier_database_entry *hash_of_EIDEs[EI_HASH_CODING_BASE];
void 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 257 "inform7/Chapter 7/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 *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 *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 = get_sort_word_count(eid);
while (*p == '0') p++;
return p;
}
#line 339 "inform7/Chapter 7/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 349 "inform7/Chapter 7/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 372 "inform7/Chapter 7/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 384 "inform7/Chapter 7/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 401 "inform7/Chapter 7/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/");
escape_apostrophes(OUT, transcoded);
WRITE("/");
Platform__transcode_ISO_string_to_locale(eid->title, transcoded);
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 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 51 "inform7/Chapter 7/Extension Census.w"
void Extensions__Census__perform(void) {
{
#line 75 "inform7/Chapter 7/Extension Census.w"
if (Files__Folders__verify_installed_extensions_tree() == FALSE) return;
}
#line 52 "inform7/Chapter 7/Extension Census.w"
;
begin_recording_census_errors();
/* count per-project extensions first */
take_census_of_domain(pathname_of_materials_extensions,
ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA);
/* and then count user-installed extensions */
take_census_of_domain(pathname_of_extensions,
ORIGIN_WAS_USER_EXTENSIONS_AREA);
/* and then count the built-in ones */
take_census_of_domain(pathname_of_built_in_extensions,
ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA);
end_recording_census_errors();
}
#line 85 "inform7/Chapter 7/Extension Census.w"
char *current_extension_domain;
void take_census_of_domain(char *pathname, int origin) {
current_extension_domain = pathname;
census_from(pathname, TRUE, origin, "");
}
#line 112 "inform7/Chapter 7/Extension Census.w"
void census_from(char *pathname, int top_level, int origin, char *parent) {
char path_to_folder[2*MAX_FILENAME_LENGTH];
char path_to_temp[MAX_FILENAME_LENGTH];
char item_name[MAX_FILENAME_LENGTH+1];
FILE *TEMPF;
int linecount = 0;
Platform__transcode_ISO_string_to_locale(pathname, path_to_folder);
sprintf(path_to_temp, "%s%cTemporary%d.txt", pathname_of_extension_docs,
FOLDER_SEPARATOR, top_level);
if (Files__Folders__write_contents_to_file(path_to_folder, path_to_temp) == FALSE) {
LOGIF(EXTENSIONS_CENSUS, "Unable to obtain contents of <%s>\n", path_to_folder);
return;
}
TEMPF = Platform__iso_fopen(path_to_temp, "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 163 "inform7/Chapter 7/Extension Census.w"
if (item_name[0] == '.') continue;
if (item_name[n] == FOLDER_SEPARATOR) {
char path_to_sub[MAX_FILENAME_LENGTH];
item_name[n] = 0; /* remove the terminal slash: it has served its purpose */
if (strcmp(item_name, "Reserved") == 0) continue;
if (Platform__strlen(item_name) > MAX_EXTENSION_TITLE_LENGTH-1) {
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) {
census_error("author name contains a full stop",
item_name, NULL, NULL, NULL); continue;
}
sprintf(path_to_sub, "%s%c%s", pathname, FOLDER_SEPARATOR, item_name);
census_from(path_to_sub, FALSE, origin, item_name);
continue;
}
census_error("non-folder found where author folders should be",
item_name, NULL, NULL, NULL); continue;
}
#line 133 "inform7/Chapter 7/Extension Census.w"
else
{
#line 199 "inform7/Chapter 7/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) {
census_error("folder or application in author folder",
parent, item_name, NULL, NULL); continue;
}
if (Platform__strlen(item_name) > MAX_EXTENSION_TITLE_LENGTH-1) {
census_error("title exceeds the maximum permitted length",
parent, item_name, NULL, NULL); continue;
}
{
#line 250 "inform7/Chapter 7/Extension Census.w"
strcpy(candidate_author_name, parent);
strcpy(candidate_title, item_name);
{
#line 269 "inform7/Chapter 7/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 252 "inform7/Chapter 7/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) {
census_error("title contains a full stop",
parent, candidate_title, NULL, NULL); continue;
}
}
#line 219 "inform7/Chapter 7/Extension Census.w"
;
{
#line 281 "inform7/Chapter 7/Extension Census.w"
FILE *EXTF;
{
#line 292 "inform7/Chapter 7/Extension Census.w"
char path_to_ext[MAX_FILENAME_LENGTH];
sprintf(path_to_ext, "%s%c%s%c%s",
current_extension_domain, FOLDER_SEPARATOR, parent, FOLDER_SEPARATOR, item_name);
EXTF = Platform__iso_fopen_caseless(path_to_ext, "r");
if (EXTF == NULL) {
census_error("file cannot be read",
parent, item_name, NULL, NULL); continue;
}
}
#line 282 "inform7/Chapter 7/Extension Census.w"
;
{
#line 307 "inform7/Chapter 7/Extension Census.w"
int titling_chars_read = 0, c;
titling_line[0] = 0;
while ((c = Text__Reader__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 283 "inform7/Chapter 7/Extension Census.w"
;
{
#line 326 "inform7/Chapter 7/Extension Census.w"
int rubric_chars_read = 0, c, found_start = FALSE;
while ((c = Text__Reader__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 284 "inform7/Chapter 7/Extension Census.w"
;
fclose(EXTF);
}
#line 220 "inform7/Chapter 7/Extension Census.w"
;
{
#line 362 "inform7/Chapter 7/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)) {
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) {
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 398 "inform7/Chapter 7/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 383 "inform7/Chapter 7/Extension Census.w"
;
if (strncmp(titling_line+start, "The ", 4) == 0) start += 4; /* advance past any |"The "| */
{
#line 414 "inform7/Chapter 7/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)) {
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 385 "inform7/Chapter 7/Extension Census.w"
;
{
#line 435 "inform7/Chapter 7/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 386 "inform7/Chapter 7/Extension Census.w"
;
}
#line 221 "inform7/Chapter 7/Extension Census.w"
;
{
#line 456 "inform7/Chapter 7/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)) {
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)) {
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)) {
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 222 "inform7/Chapter 7/Extension Census.w"
;
{
#line 484 "inform7/Chapter 7/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 223 "inform7/Chapter 7/Extension Census.w"
;
if (overridden_by_an_extension_already_found == FALSE) {
extension_census_datum *ecd;
{
#line 499 "inform7/Chapter 7/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 226 "inform7/Chapter 7/Extension Census.w"
;
}
}
#line 134 "inform7/Chapter 7/Extension Census.w"
;
}
fclose(TEMPF);
}
#line 530 "inform7/Chapter 7/Extension Census.w"
int no_census_errors = 0;
STREAM CENERR_struct;
STREAM *CENERR = NULL;
void 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 end_recording_census_errors(void) {
if (CENERR) STREAM_CLOSE(CENERR);
CENERR = NULL;
}
#line 554 "inform7/Chapter 7/Extension Census.w"
void census_error(char *message, char *auth, char *title,
char *claimed_author, char *claimed_title) {
no_census_errors++;
if (CENERR == NULL) {
char path_to_errors[MAX_FILENAME_LENGTH];
sprintf(path_to_errors, "%s%cReserved%cCensusErrors.txt",
pathname_of_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
CENERR = &CENERR_struct;
if (STREAM_OPEN_TO_FILE(CENERR, path_to_errors, UTF8_ENC) == FALSE)
Problems__Fatal__issue2("Unable to write census error log", path_to_errors);
}
Formats__HTML__open_para(CENERR, 2, "hanging");
if (claimed_author)
STREAM_WRITE(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)) STREAM_WRITE(CENERR, "<b>%s by %s</b> - %s", title, auth, message);
else STREAM_WRITE(CENERR, "<b>%s</b> - %s", auth, message);
STREAM_WRITE(CENERR, "</p>\n");
}
#line 580 "inform7/Chapter 7/Extension Census.w"
void 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 595 "inform7/Chapter 7/Extension Census.w"
void transcribe_census_errors(OUTPUT_STREAM) {
FILE *RESULTS;
char path_to_errors[MAX_FILENAME_LENGTH];
char error_line[LONGEST_POSSIBLE_CENSUS_ERROR];
if (no_census_errors == 0) return; /* nothing to include, then */
sprintf(path_to_errors, "%s%cReserved%cCensusErrors.txt",
pathname_of_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
RESULTS = Platform__iso_fopen(path_to_errors, "r");
if (RESULTS == NULL) Problems__Fatal__issue2("Unable to read census error log", path_to_errors);
{
#line 618 "inform7/Chapter 7/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 604 "inform7/Chapter 7/Extension Census.w"
;
while (Files__truncated_iso_fgets(RESULTS, error_line, LONGEST_POSSIBLE_CENSUS_ERROR) >= 1) {
WRITE("%s", error_line);
WRITE("\n");
}
fclose(RESULTS);
}
#line 643 "inform7/Chapter 7/Extension Census.w"
void Extensions__Census__write_results(OUTPUT_STREAM) {
{
#line 675 "inform7/Chapter 7/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>");
Formats__HTML__Javascript__open_file(OUT, pathname_of_extensions, 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>");
Formats__HTML__Javascript__open_file(OUT, pathname_of_materials_extensions, 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 644 "inform7/Chapter 7/Extension Census.w"
;
warn_about_census_errors(OUT);
Formats__HTML__end_html_row(OUT);
Formats__HTML__end_html_table(OUT);
WRITE("<hr>");
{
#line 715 "inform7/Chapter 7/Extension Census.w"
extension_file *ef;
LOOP_OVER(ef, extension_file)
Extensions__Dictionary__time_stamp(ef);
}
#line 649 "inform7/Chapter 7/Extension Census.w"
;
int key_vms = FALSE, key_override = FALSE, key_builtin = FALSE,
key_pspec = FALSE, key_bullet = FALSE;
{
#line 723 "inform7/Chapter 7/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 654 "inform7/Chapter 7/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 753 "inform7/Chapter 7/Extension Census.w"
char *display = "none";
if (d == CE_BY_AUTHOR) display = "block";
WRITE("<div id=\"disp%d\" style=\"display: %s;\">", d, display);
}
#line 662 "inform7/Chapter 7/Extension Census.w"
;
{
#line 778 "inform7/Chapter 7/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 = compare_ecd_by_title; break;
case CE_BY_AUTHOR: criterion = compare_ecd_by_author; break;
case CE_BY_INSTALL: criterion = compare_ecd_by_installation; break;
case CE_BY_DATE: criterion = compare_ecd_by_date; break;
case CE_BY_LENGTH: criterion = 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 663 "inform7/Chapter 7/Extension Census.w"
;
{
#line 801 "inform7/Chapter 7/Extension Census.w"
Formats__HTML__begin_html_table(OUT, FIRST_STRIPE_COLOUR, TRUE, 0, 0, 2, 0, 0);
{
#line 823 "inform7/Chapter 7/Extension Census.w"
switch (d) {
case CE_BY_TITLE:
{
#line 873 "inform7/Chapter 7/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
Formats__HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 825 "inform7/Chapter 7/Extension Census.w"
;
WRITE("Extensions in alphabetical order");
{
#line 881 "inform7/Chapter 7/Extension Census.w"
WRITE("</font>");
Formats__HTML__end_html_row(OUT);
}
#line 827 "inform7/Chapter 7/Extension Census.w"
;
break;
case CE_BY_DATE:
{
#line 873 "inform7/Chapter 7/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
Formats__HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 830 "inform7/Chapter 7/Extension Census.w"
;
WRITE("Extensions in order of date used (most recent first)");
{
#line 881 "inform7/Chapter 7/Extension Census.w"
WRITE("</font>");
Formats__HTML__end_html_row(OUT);
}
#line 832 "inform7/Chapter 7/Extension Census.w"
;
break;
case CE_BY_LENGTH:
{
#line 873 "inform7/Chapter 7/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
Formats__HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 835 "inform7/Chapter 7/Extension Census.w"
;
WRITE("Extensions in order of word count (longest first)");
{
#line 881 "inform7/Chapter 7/Extension Census.w"
WRITE("</font>");
Formats__HTML__end_html_row(OUT);
}
#line 837 "inform7/Chapter 7/Extension Census.w"
;
break;
}
}
#line 802 "inform7/Chapter 7/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 844 "inform7/Chapter 7/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 873 "inform7/Chapter 7/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
Formats__HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 847 "inform7/Chapter 7/Extension Census.w"
;
{
#line 887 "inform7/Chapter 7/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 (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 848 "inform7/Chapter 7/Extension Census.w"
;
{
#line 881 "inform7/Chapter 7/Extension Census.w"
WRITE("</font>");
Formats__HTML__end_html_row(OUT);
}
#line 849 "inform7/Chapter 7/Extension Census.w"
;
stripe = 0;
}
if ((d == CE_BY_INSTALL) && (installation_region(ecd) != current_installation)) {
current_installation = installation_region(ecd);
{
#line 873 "inform7/Chapter 7/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
Formats__HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 854 "inform7/Chapter 7/Extension Census.w"
;
{
#line 911 "inform7/Chapter 7/Extension Census.w"
switch (current_installation) {
case 0: WRITE("Supplied in the .materials folder&nbsp;&nbsp;<small>%s</small>",
pathname_of_materials_extensions); 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>%s</small>",
pathname_of_extensions);
break;
}
}
#line 855 "inform7/Chapter 7/Extension Census.w"
;
{
#line 881 "inform7/Chapter 7/Extension Census.w"
WRITE("</font>");
Formats__HTML__end_html_row(OUT);
}
#line 856 "inform7/Chapter 7/Extension Census.w"
;
stripe = 0;
}
}
#line 808 "inform7/Chapter 7/Extension Census.w"
;
stripe = 1 - stripe;
if (stripe == 0)
Formats__HTML__first_html_column_coloured(OUT, 0, SECOND_STRIPE_COLOUR, 0);
else
Formats__HTML__first_html_column_coloured(OUT, 0, FIRST_STRIPE_COLOUR, 0);
{
#line 930 "inform7/Chapter 7/Extension Census.w"
{
#line 947 "inform7/Chapter 7/Extension Census.w"
char *bulletornot = UNINDEXED_SYMBOL;
if (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 976 "inform7/Chapter 7/Extension Census.w"
int rw1 = lexer_wordcount, rw2;
Text__feed_into_lexer(ecd->VM_requirement, FALSE, NULL);
rw2 = lexer_wordcount - 1;
Text__feed_into_lexer("Another firebreak. ", FALSE, NULL);
WRITE("&nbsp;");
Code__VirtualMachines__write_icons(OUT, rw1+2, rw2-2);
}
#line 965 "inform7/Chapter 7/Extension Census.w"
;
key_vms = TRUE;
}
}
#line 930 "inform7/Chapter 7/Extension Census.w"
;
Formats__HTML__next_html_column_nw(OUT, 0);
if (d != CE_BY_TITLE) {
{
#line 986 "inform7/Chapter 7/Extension Census.w"
if (ecd->version_text[0])
WRITE("<small>v&nbsp;%s</small>", ecd->version_text);
else
WRITE("<small>--</small>");
}
#line 933 "inform7/Chapter 7/Extension Census.w"
;
Formats__HTML__next_html_column_nw(OUT, 0);
}
{
#line 994 "inform7/Chapter 7/Extension Census.w"
char *opener = "<img src='inform:/doc_images/folder4.png' border=0>";
char *area = pathname_of_extensions;
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_materials_extensions;
}
if (ecd->built_in)
WRITE("%s", opener);
else Formats__HTML__Javascript__open_file(OUT, area,
ecd->ecd_id.raw_author_name, opener);
}
#line 936 "inform7/Chapter 7/Extension Census.w"
;
Formats__HTML__next_html_column_w(OUT, 0);
{
#line 1012 "inform7/Chapter 7/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) && (*(ecd->rubric)))
WRITE("<small>%s</small>", ecd->rubric);
else
WRITE("<small>--</small>");
}
}
#line 938 "inform7/Chapter 7/Extension Census.w"
;
}
#line 814 "inform7/Chapter 7/Extension Census.w"
;
Formats__HTML__end_html_row(OUT);
}
{
#line 863 "inform7/Chapter 7/Extension Census.w"
{
#line 873 "inform7/Chapter 7/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
Formats__HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 863 "inform7/Chapter 7/Extension Census.w"
;
WRITE("<small>%d extensions installed</small>", no_entries);
{
#line 881 "inform7/Chapter 7/Extension Census.w"
WRITE("</font>");
Formats__HTML__end_html_row(OUT);
}
#line 865 "inform7/Chapter 7/Extension Census.w"
;
}
#line 817 "inform7/Chapter 7/Extension Census.w"
;
Formats__HTML__end_html_table(OUT);
}
#line 664 "inform7/Chapter 7/Extension Census.w"
;
WRITE("</div>\n");
}
{
#line 762 "inform7/Chapter 7/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>");
Code__VirtualMachines__write_key(OUT);
}
}
}
#line 667 "inform7/Chapter 7/Extension Census.w"
;
transcribe_census_errors(OUT);
Memory__I7_free(sorted_census_results, EXTENSION_DICTIONARY_MREASON);
}
#line 1026 "inform7/Chapter 7/Extension Census.w"
int 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 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 1045 "inform7/Chapter 7/Extension Census.w"
int 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 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 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 = installation_region(e1) - installation_region(e2);
if (d != 0) return d;
return Extensions__IDs__compare_by_title(&(e1->ecd_id), &(e2->ecd_id));
}
int 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 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 7/Extension Dictionary.w"
void Extensions__Dictionary__Entries__log(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 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 7/Extension Dictionary.w"
void 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 7/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 7/Extension Dictionary.w"
void Extensions__Dictionary__Entries__new(char *category, extension_file *ef, int w1, int w2) {
char headword[MAX_ED_HEADWORD_LENGTH];
if ((w1<0) || (w2<w1)) return; /* a safety precaution: never index the empty text */
Text__print_raw_text_to_string_truncated(w1, w2, headword, MAX_ED_HEADWORD_LENGTH);
new_dictionary_entry_raw(category, ef->ef_id.author_name, ef->ef_id.title, headword);
}
void Extensions__Dictionary__Entries__new_str(char *category, extension_file *ef, char *headword) {
new_dictionary_entry_raw(category, ef->ef_id.author_name, ef->ef_id.title, headword);
}
void 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 221 "inform7/Chapter 7/Extension Dictionary.w"
void Extensions__Dictionary__load(void) {
FILE *DICTF; FILE *EMPTY_DICTF;
char line_entry[MAX_ED_LINE_LENGTH];
{
#line 246 "inform7/Chapter 7/Extension Dictionary.w"
char path_to_dictionary[MAX_FILENAME_LENGTH];
sprintf(path_to_dictionary, "%s%cReserved%cDictionary.txt",
pathname_of_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
DICTF = Platform__iso_fopen(path_to_dictionary, "r");
if (DICTF == NULL) {
if (Files__Folders__verify_library_folder("Inform", "Extensions", NULL, "Reserved") == 0)
return;
LOGIF(EXTENSIONS_CENSUS, "Creating new empty dictionary file\n");
EMPTY_DICTF = Platform__iso_fopen(path_to_dictionary, "w");
if (EMPTY_DICTF == NULL) return;
fclose(EMPTY_DICTF);
DICTF = Platform__iso_fopen(path_to_dictionary, "r");
if (DICTF == NULL)
Problems__Fatal__issue2("Unable to open dictionary file", path_to_dictionary);
}
}
#line 225 "inform7/Chapter 7/Extension Dictionary.w"
;
LOGIF(EXTENSIONS_CENSUS, "Reading dictionary file\n");
while (Files__truncated_iso_fgets(DICTF, line_entry, MAX_ED_LINE_LENGTH-1) >= 1)
{
#line 270 "inform7/Chapter 7/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) new_dictionary_entry_raw(category, author, title, headword);
}
#line 229 "inform7/Chapter 7/Extension Dictionary.w"
;
LOGIF(EXTENSIONS_CENSUS, "Finished reading dictionary file\n");
fclose(DICTF);
}
#line 292 "inform7/Chapter 7/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,
Text__Reader__sf_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__Entries__new_str("indexing", ef, dbuff);
}
#line 312 "inform7/Chapter 7/Extension Dictionary.w"
void Extensions__Dictionary__write_back(void) {
extension_dictionary_entry *ede;
STREAM DICTF_struct;
STREAM *DICTF = &DICTF_struct;
char path_to_dictionary[MAX_FILENAME_LENGTH];
if (Files__Folders__verify_installed_extensions_tree() == FALSE) return;
sprintf(path_to_dictionary, "%s%cReserved%cDictionary.txt",
pathname_of_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
if (STREAM_OPEN_TO_FILE(DICTF, path_to_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 347 "inform7/Chapter 7/Extension Dictionary.w"
STREAM_WRITE(DICTF, "|%s|%s|%s|%s|\n",
ede->ede_id.author_name, ede->ede_id.title,
ede->entry_text, ede->type);
}
#line 328 "inform7/Chapter 7/Extension Dictionary.w"
;
} else LOGIF(EXTENSIONS_CENSUS, "Suppressing $d\n", ede);
LOGIF(EXTENSIONS_CENSUS, "Finished writing dictionary file\n");
STREAM_CLOSE(DICTF);
}
#line 365 "inform7/Chapter 7/Extension Dictionary.w"
int 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 411 "inform7/Chapter 7/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 372 "inform7/Chapter 7/Extension Dictionary.w"
;
if (no_entries == 0) {
first_in_sorted_dictionary = NULL;
return 0;
}
{
#line 429 "inform7/Chapter 7/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 379 "inform7/Chapter 7/Extension Dictionary.w"
;
qsort(sorted_extension_dictionary, (size_t) no_entries, sizeof(extension_dictionary_entry *),
compare_ed_entries);
{
#line 441 "inform7/Chapter 7/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 384 "inform7/Chapter 7/Extension Dictionary.w"
;
{
#line 452 "inform7/Chapter 7/Extension Dictionary.w"
Memory__I7_free(sorted_extension_dictionary, EXTENSION_DICTIONARY_MREASON);
}
#line 385 "inform7/Chapter 7/Extension Dictionary.w"
;
LOGIF(EXTENSIONS_CENSUS, "Sorted dictionary: %d entries\n", no_entries);
return no_entries;
}
#line 460 "inform7/Chapter 7/Extension Dictionary.w"
int 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 476 "inform7/Chapter 7/Extension Dictionary.w"
known_extension_clash *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 540 "inform7/Chapter 7/Extension Dictionary.w"
void 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 570 "inform7/Chapter 7/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 548 "inform7/Chapter 7/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 583 "inform7/Chapter 7/Extension Dictionary.w"
while (kec) {
if (Extensions__IDs__match(rightx, &(kec->rightx->ede_id))) {
kec->number_clashes++; return;
}
if (kec->next == NULL) {
kec->next = kec_new(left, right, FALSE); return;
}
kec = kec->next;
}
}
#line 556 "inform7/Chapter 7/Extension Dictionary.w"
;
return;
}
kec = kec_new(left, right, TRUE);
}
#line 597 "inform7/Chapter 7/Extension Dictionary.w"
void list_known_extension_clashes(OUTPUT_STREAM) {
known_extension_clash *kec;
if (NUMBER_CREATED(known_extension_clash) == 0) return;
{
#line 610 "inform7/Chapter 7/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 600 "inform7/Chapter 7/Extension Dictionary.w"
;
LOOP_OVER(kec, known_extension_clash)
if (kec->first_known)
{
#line 622 "inform7/Chapter 7/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__print_literal_string_to_file(OUT, example->leftx->entry_text);
WRITE(")");
if (example->next) WRITE("; ");
}
WRITE("<p>\n");
}
#line 603 "inform7/Chapter 7/Extension Dictionary.w"
;
}
#line 645 "inform7/Chapter 7/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>");
Formats__HTML__end_html_row(OUT);
Formats__HTML__end_html_table(OUT);
int n;
char first_letter = 'a';
extension_dictionary_entry *ede, *previous_ede, *next_ede;
erase_entries_of_uninstalled_extensions();
n = 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 681 "inform7/Chapter 7/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;
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__print_literal_string_to_file(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 665 "inform7/Chapter 7/Extension Dictionary.w"
;
}
list_known_extension_clashes(OUT);
}
#line 14 "inform7/Chapter 7/Extension Documentation.w"
void Extensions__Documentation__write_detailed(extension_file *ef) {
write_extension_documentation(NULL, ef);
}
void Extensions__Documentation__write_sketchy(extension_census_datum *ecd) {
write_extension_documentation(ecd, NULL);
}
#line 40 "inform7/Chapter 7/Extension Documentation.w"
void write_extension_documentation(extension_census_datum *ecd, extension_file *ef) {
int c, eg_count;
eg_count = write_extension_documentation_page(ecd, ef, -1);
for (c=1; c<=eg_count; c++)
write_extension_documentation_page(ecd, ef, c);
}
#line 61 "inform7/Chapter 7/Extension Documentation.w"
int write_extension_documentation_page(extension_census_datum *ecd, extension_file *ef,
int eg_number) {
extension_identifier *eid = NULL;
STREAM DOCF_struct;
STREAM *DOCF = &DOCF_struct;
FILE *TEST_DOCF;
int page_exists_already, no_egs = 0;
char leafname[MAX_FILENAME_LENGTH], pathname[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);
{
#line 104 "inform7/Chapter 7/Extension Documentation.w"
strcpy(leafname, eid->title);
if (eg_number > 0) sprintf(leafname+Platform__strlen(leafname), "-eg%d", eg_number);
sprintf(pathname, "%s%cExtensions%c%s%c%s.html", pathname_of_extension_docs,
FOLDER_SEPARATOR, FOLDER_SEPARATOR, eid->author_name, FOLDER_SEPARATOR, leafname);
}
#line 75 "inform7/Chapter 7/Extension Documentation.w"
;
page_exists_already = FALSE;
TEST_DOCF = Platform__iso_fopen(pathname, "r");
if (TEST_DOCF) { page_exists_already = TRUE; fclose(TEST_DOCF); }
LOGIF(EXTENSIONS_CENSUS, "WEDP %s: %s\n", (page_exists_already)?"exists":"does not exist",
pathname);
if (ecd) {
if ((page_exists_already == FALSE) || (census_mode))
{
#line 120 "inform7/Chapter 7/Extension Documentation.w"
int aw1 = lexer_wordcount, aw2, tw1, tw2;
Text__feed_into_lexer(eid->raw_author_name, FALSE, NULL);
Text__feed_into_lexer(" ", FALSE, NULL);
aw2 = lexer_wordcount - 1;
tw1 = lexer_wordcount;
Text__feed_into_lexer(eid->raw_title, FALSE, NULL);
Text__feed_into_lexer(" ", FALSE, NULL);
tw2 = lexer_wordcount - 1;
Text__feed_into_lexer("This sentence provides a firebreak, no more. ", FALSE, NULL);
if (parse_nt_against_word_range(unsuitable_name_NTM, aw1, aw2, NULL, NULL)) return 0;
if (parse_nt_against_word_range(unsuitable_name_NTM, tw1, tw2, NULL, NULL)) return 0;
ef = Extensions__Inclusion__load(aw1, aw2, tw1, tw2, -1, -1, -1);
if (ef == NULL) return 0; /* shouldn't happen: it was there only moments ago */
write_extension_documentation(NULL, ef);
}
#line 85 "inform7/Chapter 7/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 (Files__Folders__verify_library_folder("Inform", "Documentation", "Extensions", eid->author_name) == 0)
return 0;
if (STREAM_OPEN_TO_FILE(DOCF, pathname, UTF8_ENC) == FALSE)
return 0; /* if we lack permissions, e.g., then write no documentation */
{
#line 140 "inform7/Chapter 7/Extension Documentation.w"
char path_to_model[MAX_FILENAME_LENGTH];
char line_of_template[LONGEST_LINE_IN_EX_TEMPLATE];
FILE *TEMPLATE;
int skipping_between_markers = FALSE;
sprintf(path_to_model, "%s%cReserved%c%s",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR,
EXTENSION_FILE_MODEL_HTML);
TEMPLATE = Platform__iso_fopen(path_to_model, "r");
if (TEMPLATE == NULL)
Problems__Fatal__issue2("Unable to open model extension documentation file for reading",
path_to_model);
while (!(feof(TEMPLATE))) {
int n = Files__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 169 "inform7/Chapter 7/Extension Documentation.w"
STREAM_WRITE(DOCF, "<p>");
if (Extensions__IDs__is_standard_rules(eid) == FALSE)
{
#line 187 "inform7/Chapter 7/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);
Formats__HTML__Javascript__paste(DOCF, -1, -1, inclusion_text);
STREAM_WRITE(DOCF, "&nbsp;");
}
#line 171 "inform7/Chapter 7/Extension Documentation.w"
;
STREAM_WRITE(DOCF, "<b>");
Extensions__IDs__write_to_HTML_file(DOCF, eid, TRUE);
STREAM_WRITE(DOCF, "</b><p><small>");
{
#line 195 "inform7/Chapter 7/Extension Documentation.w"
int rw1 = ef->VM_restriction_w1, rw2 = ef->VM_restriction_w2;
if (rw1 >= 0) {
Text__print_raw_text_to_stream(rw1, rw2, DOCF);
STREAM_WRITE(DOCF, "&nbsp;");
Code__VirtualMachines__write_icons(DOCF, rw1, rw2);
}
}
#line 175 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 205 "inform7/Chapter 7/Extension Documentation.w"
char the_version[MAX_VERSION_NUMBER_LENGTH+1];
if (ef->version_loaded >= 0)
Text__print_raw_text_to_string(ef->version_loaded, ef->version_loaded, the_version);
else the_version[0] = 0;
if (the_version[0]) STREAM_WRITE(DOCF, "<p>Version %s", the_version);
if (ef->loaded_from_built_in_area) {
if (the_version[0] == 0) STREAM_WRITE(DOCF, "<p>Extension");
STREAM_WRITE(DOCF, " built in to Inform");
}
}
#line 176 "inform7/Chapter 7/Extension Documentation.w"
;
STREAM_WRITE(DOCF, "</small><p>");
{
#line 219 "inform7/Chapter 7/Extension Documentation.w"
if (ef->rubric_as_lexed[0])
STREAM_WRITE(DOCF, "%s<p>", ef->rubric_as_lexed);
if (ef->extra_credit_as_lexed[0])
STREAM_WRITE(DOCF, "<i>%s</i><p>", ef->extra_credit_as_lexed);
}
#line 178 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 230 "inform7/Chapter 7/Extension Documentation.w"
if (ef->doc_w1 >= 0)
Extensions__Documentation__HTML__set_table_of_contents(ef->doc_w1, ef->doc_w2, DOCF, leafname);
}
#line 179 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 249 "inform7/Chapter 7/Extension Documentation.w"
Extensions__Dictionary__erase_entries(ef);
Extensions__Dictionary__time_stamp(ef);
{
#line 270 "inform7/Chapter 7/Extension Documentation.w"
kind *K;
int kc = 0;
LOOP_OVER_BASE_KINDS(K) {
parse_node *S = Kinds__get_creating_sentence(K);
if (S) {
int z1 = S->word_ref1;
if (Text__file_of_origin(z1) == ef->read_into_file) {
int w1, w2;
Kinds__get_name(K, &w1, &w2, FALSE);
kc = document_headword(DOCF, kc, ef, "Kinds", "kind", w1, w2);
kind *S = Kinds__super(K);
if (S) {
Kinds__get_name(S, &w1, &w2, FALSE);
if (w1 >= 0) {
STREAM_WRITE(DOCF, " (a kind of ");
Text__print_raw_text_to_stream(w1, w2, DOCF);
STREAM_WRITE(DOCF, ")");
}
}
}
}
}
if (kc != 0) STREAM_WRITE(DOCF, "<p>");
}
#line 252 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 297 "inform7/Chapter 7/Extension Documentation.w"
instance *I;
int kc = 0;
LOOP_OVER_OBJECT_INSTANCES(I) {
int ow1, ow2;
Data__Instances__get_name(I, &ow1, &ow2, FALSE);
if ((Data__Instances__get_creating_sentence(I)) && (ow1 >= 0)) {
int z1 = Data__Instances__get_creating_sentence(I)->word_ref1;
if (Text__file_of_origin(z1) == ef->read_into_file) {
char name_of_its_kind[512];
kind *k = Data__Instances__kind(I);
int w1 = -1, w2 = -1;
Kinds__get_name(k, &w1, &w2, FALSE);
Text__print_raw_text_to_string(w1, w2, name_of_its_kind);
kc = document_headword(DOCF, kc, ef, "Physical creations",
name_of_its_kind, ow1, ow2);
STREAM_WRITE(DOCF, " (a ");
Text__print_raw_text_to_stream(w1, w2, DOCF);
STREAM_WRITE(DOCF, ")");
}
}
}
if (kc != 0) STREAM_WRITE(DOCF, "<p>");
}
#line 253 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 323 "inform7/Chapter 7/Extension Documentation.w"
nonlocal_variable *q;
int kc = 0;
LOOP_OVER(q, nonlocal_variable)
if ((q->word_ref1 >= 0) &&
(Data__NonlocalVariables__is_global(q)) &&
(Text__file_of_origin(q->word_ref1) == ef->read_into_file) &&
(Parser__Sentences__Headings__indexed(
Parser__Sentences__Headings__heading_of(Text__word_location(q->word_ref1)))) &&
(parse_nt_against_word_range(value_understood_variable_name_NTM, q->word_ref1, q->word_ref2, NULL, NULL) == FALSE))
kc = document_headword(DOCF, kc, ef, "Values that vary", "value",
q->word_ref1, q->word_ref2);
if (kc != 0) STREAM_WRITE(DOCF, "<p>");
}
#line 255 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 339 "inform7/Chapter 7/Extension Documentation.w"
instance *q;
int kc = 0;
LOOP_OVER_ENUMERATION_INSTANCES(q) {
int nw1, nw2;
Data__Instances__get_name(q, &nw1, &nw2, FALSE);
if ((nw1 >= 0) && (Text__file_of_origin(nw1) == ef->read_into_file))
kc = document_headword(DOCF, kc, ef, "Values", "value", nw1, nw2);
}
if (kc != 0) STREAM_WRITE(DOCF, "<p>");
}
#line 256 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 352 "inform7/Chapter 7/Extension Documentation.w"
named_action_pattern *nap;
int kc = 0;
LOOP_OVER(nap, named_action_pattern)
if (Text__file_of_origin(nap->word_ref1) == ef->read_into_file)
kc = document_headword(DOCF, kc, ef, "Kinds of action", "kind of action",
nap->word_ref1, nap->word_ref2);
if (kc != 0) STREAM_WRITE(DOCF, "<p>");
}
#line 258 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 363 "inform7/Chapter 7/Extension Documentation.w"
action_name *acn;
int kc = 0;
LOOP_OVER(acn, action_name)
if (Text__file_of_origin(acn->word_ref1) == ef->read_into_file)
kc = document_headword(DOCF, kc, ef, "Actions", "action",
acn->word_ref1, acn->word_ref2);
if (kc != 0) STREAM_WRITE(DOCF, "<p>");
}
#line 259 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 374 "inform7/Chapter 7/Extension Documentation.w"
Index__Lexicon__list_verbs_in_file(DOCF, ef->read_into_file, ef);
}
#line 261 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 379 "inform7/Chapter 7/Extension Documentation.w"
adjectival_phrase *adj;
int kc = 0;
LOOP_OVER(adj, adjectival_phrase) {
int w1, w2;
Semantics__Adjectives__Meanings__get_text(adj, &w1, &w2, FALSE);
if ((w1 >= 0) && (Text__file_of_origin(w1) == ef->read_into_file))
kc = document_headword(DOCF, kc, ef, "Adjectives", "adjective", w1, w2);
}
if (kc != 0) STREAM_WRITE(DOCF, "<p>");
}
#line 262 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 392 "inform7/Chapter 7/Extension Documentation.w"
property *prn;
int kc = 0;
LOOP_OVER(prn, property)
if ((prn->word_ref1 >= 0) &&
(Properties__is_shown_in_index(prn)) &&
(Text__file_of_origin(prn->word_ref1) == ef->read_into_file))
kc = document_headword(DOCF, kc, ef, "Properties", "property",
prn->word_ref1, prn->word_ref2);
if (kc != 0) STREAM_WRITE(DOCF, "<p>");
}
#line 263 "inform7/Chapter 7/Extension Documentation.w"
;
{
#line 405 "inform7/Chapter 7/Extension Documentation.w"
use_option *uo;
int kc = 0;
LOOP_OVER(uo, use_option)
if ((uo->word_ref1 >= 0) &&
(Text__file_of_origin(uo->word_ref1) == ef->read_into_file))
kc = document_headword(DOCF, kc, ef, "Use options", "use option",
uo->word_ref1, uo->word_ref2);
if (kc != 0) STREAM_WRITE(DOCF, "<p>");
}
#line 265 "inform7/Chapter 7/Extension Documentation.w"
;
}
#line 180 "inform7/Chapter 7/Extension Documentation.w"
;
STREAM_WRITE(DOCF, "<p><hr><p>");
{
#line 236 "inform7/Chapter 7/Extension Documentation.w"
if (ef->doc_w1 >= 0)
no_egs = Extensions__Documentation__HTML__set_body_text(ef->doc_w1, ef->doc_w2, DOCF, eg_number, leafname);
else
STREAM_WRITE(DOCF, "The extension provides no documentation.");
}
#line 182 "inform7/Chapter 7/Extension Documentation.w"
;
}
#line 157 "inform7/Chapter 7/Extension Documentation.w"
;
skipping_between_markers = TRUE;
}
if (skipping_between_markers == FALSE) STREAM_WRITE(DOCF, "%s", line_of_template);
if (strcmp(line_of_template, "<a name=off>") == 0)
skipping_between_markers = FALSE;
}
fclose(TEMPLATE);
}
#line 96 "inform7/Chapter 7/Extension Documentation.w"
;
STREAM_CLOSE(DOCF);
return no_egs;
}
#line 419 "inform7/Chapter 7/Extension Documentation.w"
int document_headword(OUTPUT_STREAM, int kc, extension_file *ef, char *par_heading,
char *category, int w1, int w2) {
if (kc++ == 0) WRITE("%s: ", par_heading);
else WRITE(", ");
WRITE("<b>");
Text__print_raw_text_to_stream(w1, w2, OUT);
WRITE("</b>");
Extensions__Dictionary__Entries__new(category, ef, w1, w2);
return kc;
}
#line 93 "inform7/Chapter 8/Traverse for Assertions.w"
int sentence_handlers_initialised = FALSE;
parse_node *assembly_position = NULL; /* where assembled sentences are added */
void Parser__Assertions__traverse(int pass) {
Parser__Assertions__new_discussion(); /* clear memory of what the subject and object of discussion are */
traverse = pass;
trace_sentences = FALSE;
if (sentence_handlers_initialised == FALSE)
{
#line 138 "inform7/Chapter 8/Traverse for Assertions.w"
sentence_handlers_initialised = TRUE;
{
#line 152 "inform7/Chapter 8/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 139 "inform7/Chapter 8/Traverse for Assertions.w"
;
Config__Template__register_sentence_handlers();
}
#line 101 "inform7/Chapter 8/Traverse for Assertions.w"
;
parse_node *p, *last = NULL;
TREE_LOOP(p) {
assembly_position = current_sentence;
{
#line 116 "inform7/Chapter 8/Traverse for Assertions.w"
if ((p->down) && (p->down->next)) {
parse_node *apparent_subject = p->down->next;
if (Parser__Nodes__type(apparent_subject) == WITH_NT) {
int w1 = -1, w2 = -1;
if (apparent_subject->down) {
w1 = apparent_subject->down->word_ref1;
if (apparent_subject->down->next)
w2 = apparent_subject->down->next->word_ref2;
}
meaning_list *ml = Parser__SP__parse_excerpt(MISCELLANEOUS_MC, w1, w2);
if ((ml) && (Semantics__Nouns__ExcerptMeanings__get_secondary_code(Parser__SP__MeaningLists__meaning(ml)) == ACTION_NAME_SMC)) {
Parser__Nodes__set_node_type(apparent_subject, PROPER_NOUN_NT);
apparent_subject->word_ref1 = w1;
apparent_subject->word_ref2 = w2;
apparent_subject->down = NULL;
}
}
}
}
#line 106 "inform7/Chapter 8/Traverse for Assertions.w"
;
{
#line 161 "inform7/Chapter 8/Traverse for Assertions.w"
Parser__SP__MeaningLists__finish_this_session();
if ((trace_sentences) && (Parser__Nodes__type(p) != TRACE_NT))
LOG("\n[$W]\n", p->word_ref1, p->word_ref2);
last = p;
{
#line 179 "inform7/Chapter 8/Traverse for Assertions.w"
if (((Parser__Nodes__type(p) >= 0) && (Parser__Nodes__type(p) < MAX_OF_NTS_AND_VBS))
&& (how_to_handle_nodes[Parser__Nodes__type(p)])) {
int desired = how_to_handle_nodes[Parser__Nodes__type(p)]->handle_on_traverse;
if (((traverse == desired) || (desired == 0)) &&
(how_to_handle_nodes[Parser__Nodes__type(p)]->handling_routine))
(*(how_to_handle_nodes[Parser__Nodes__type(p)]->handling_routine))(p);
continue;
}
}
#line 166 "inform7/Chapter 8/Traverse for Assertions.w"
;
Parser__Nodes__log_subtree(p, 1);
if (p->down) internal_error_on_node_type(p->down);
else {
LOG("$T\n", p);
internal_error("uncaught assertion");
}
}
#line 107 "inform7/Chapter 8/Traverse for Assertions.w"
;
}
if (pass == 2)
{
#line 210 "inform7/Chapter 8/Traverse for Assertions.w"
current_sentence = last;
assembly_position = current_sentence;
Config__Plugins__Call__complete_model(1);
for (p = last, TREE_NEXT(p); p; TREE_NEXT(p))
{
#line 161 "inform7/Chapter 8/Traverse for Assertions.w"
Parser__SP__MeaningLists__finish_this_session();
if ((trace_sentences) && (Parser__Nodes__type(p) != TRACE_NT))
LOG("\n[$W]\n", p->word_ref1, p->word_ref2);
last = p;
{
#line 179 "inform7/Chapter 8/Traverse for Assertions.w"
if (((Parser__Nodes__type(p) >= 0) && (Parser__Nodes__type(p) < MAX_OF_NTS_AND_VBS))
&& (how_to_handle_nodes[Parser__Nodes__type(p)])) {
int desired = how_to_handle_nodes[Parser__Nodes__type(p)]->handle_on_traverse;
if (((traverse == desired) || (desired == 0)) &&
(how_to_handle_nodes[Parser__Nodes__type(p)]->handling_routine))
(*(how_to_handle_nodes[Parser__Nodes__type(p)]->handling_routine))(p);
continue;
}
}
#line 166 "inform7/Chapter 8/Traverse for Assertions.w"
;
Parser__Nodes__log_subtree(p, 1);
if (p->down) internal_error_on_node_type(p->down);
else {
LOG("$T\n", p);
internal_error("uncaught assertion");
}
}
#line 214 "inform7/Chapter 8/Traverse for Assertions.w"
;
}
#line 110 "inform7/Chapter 8/Traverse for Assertions.w"
;
}
#line 224 "inform7/Chapter 8/Traverse for Assertions.w"
sentence_handler TRACE_SH_handler =
{ TRACE_NT, -1, 0, switch_sentence_trace };
void switch_sentence_trace(parse_node *PN) {
if (PN->word_ref2 > PN->word_ref1) {
int tr = telemetry_recording;
telemetry_recording = TRUE;
Log__Telemetry__write_note(Text__word_text(PN->word_ref2));
telemetry_recording = FALSE;
Problems__sentence_problem(_P_(C8TelemetryAccepted),
"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 250 "inform7/Chapter 8/Traverse for Assertions.w"
sentence_handler SENTENCE_SH_handler =
{ SENTENCE_NT, -1, 0, handle_sentence_with_primary_verb };
void handle_sentence_with_primary_verb(parse_node *p) {
prevailing_mood = UNKNOWN_CE;
if (Parser__Nodes__int_annotation(p, language_element_ANNOT)) return;
if (p->down == NULL)
{
#line 269 "inform7/Chapter 8/Traverse for Assertions.w"
if ((p->word_ref1 == p->word_ref2) &&
(Text__Vocabulary__test_flags(p->word_ref1, TEXT_MC+TEXTWITHSUBS_MC))) {
if (traverse == 2) set_appearance(p->word_ref1);
return;
}
parse_nt_against_word_range(no_verb_diagnosis_NTM, p->word_ref1, p->word_ref2, NULL, NULL);
return;
}
#line 256 "inform7/Chapter 8/Traverse for Assertions.w"
;
internal_error_if_node_type_wrong(p->down, VERB_NT);
prevailing_mood = Parser__Nodes__int_annotation(p->down, verbal_certainty_ANNOT);
{
#line 359 "inform7/Chapter 8/Traverse for Assertions.w"
if ((p->down->next) && (p->down->next->next)) {
int sw1 = p->down->next->word_ref1, sw2 = p->down->next->word_ref2;
int ow1 = p->down->next->next->word_ref1, ow2 = p->down->next->next->word_ref2;
if ((Text__mismatched_brackets(sw1, sw2)) || (Text__mismatched_brackets(ow1, ow2))) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, sw2 + 1, sw2 + 1);
Problems__quote_words(3, sw1, sw2);
Problems__quote_words(4, ow1, ow2);
Problems__handmade_problem(_P_(BelievedImpossible));
if (ow1 >= 0)
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 259 "inform7/Chapter 8/Traverse for Assertions.w"
;
{
#line 283 "inform7/Chapter 8/Traverse for Assertions.w"
int vn = Parser__Nodes__int_annotation(p->down, verb_id_ANNOT);
if ((vn < 0) || (vn >= MAX_OF_NTS_AND_VBS)) {
LOG("Unimplemented verb %d\n", Parser__Nodes__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 260 "inform7/Chapter 8/Traverse for Assertions.w"
;
}
#line 301 "inform7/Chapter 8/Traverse for Assertions.w"
int no_verb_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 310 "inform7/Chapter 8/Traverse for Assertions.w"
Problems__sentence_problem(_P_(C8RuleWithoutColon),
"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 302 "inform7/Chapter 8/Traverse for Assertions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 321 "inform7/Chapter 8/Traverse for Assertions.w"
Problems__sentence_problem(_P_(C8IfOutsidePhrase),
"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 303 "inform7/Chapter 8/Traverse for Assertions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 333 "inform7/Chapter 8/Traverse for Assertions.w"
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C8NoSuchVerbComma));
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 304 "inform7/Chapter 8/Traverse for Assertions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 349 "inform7/Chapter 8/Traverse for Assertions.w"
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C8NoSuchVerb));
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 305 "inform7/Chapter 8/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 306 "inform7/Chapter 8/Traverse for Assertions.w"
#line 394 "inform7/Chapter 8/Traverse for Assertions.w"
void set_appearance(int wn) {
if (near_start_of_extension >= 1)
{
#line 411 "inform7/Chapter 8/Traverse for Assertions.w"
source_file *pos = Text__file_of_origin(wn);
extension_file *ef = Text__Reader__sf_get_extension_corresponding(pos);
if (ef) {
Text__dequote_word(wn);
char *quoted_text = Text__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 395 "inform7/Chapter 8/Traverse for Assertions.w"
;
inference_subject *infs = Parser__Assertions__get_current_subject();
if (infs == NULL)
{
#line 427 "inform7/Chapter 8/Traverse for Assertions.w"
Problems__sentence_problem(_P_(C8TextWithoutSubject),
"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 398 "inform7/Chapter 8/Traverse for Assertions.w"
;
specification *spec = Specifications__Values__new_actual_CONSTANT(K_text);
spec->word_ref1 = wn; spec->word_ref2 = wn;
Properties__Appearance__infer(infs, spec);
}
#line 460 "inform7/Chapter 8/Traverse for Assertions.w"
inference_subject *object_of_sentences = NULL, *subject_of_sentences = NULL;
int subject_seems_to_be_plural = FALSE;
inference_subject *Parser__Assertions__get_current_subject(void) {
return subject_of_sentences;
}
inference_subject *Parser__Assertions__get_current_object(void) {
return object_of_sentences;
}
int Parser__Assertions__get_current_subject_plurality(void) {
return subject_seems_to_be_plural;
}
#line 490 "inform7/Chapter 8/Traverse for Assertions.w"
void Parser__Assertions__new_discussion(void) {
subject_of_sentences = NULL; object_of_sentences = NULL;
}
void Parser__Assertions__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 (current_sentence->word_ref2 - current_sentence->word_ref1 > 0)
near_start_of_extension = 0;
Parser__Nodes__set_interpretation_of_subject(current_sentence, subject_of_sentences);
if (Parser__Nodes__has_annotation(current_sentence, implicit_in_creation_of_ANNOT))
return;
if ((Plugins__Map__is_a_direction(infsx)) &&
((World__Subjects__as_instance(infsx) == NULL) ||
(World__Subjects__as_instance(infsy_full)))) infsx = NULL;
if (infsx) subject_of_sentences = infsx;
if ((infsy) && (World__Subjects__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 522 "inform7/Chapter 8/Traverse for Assertions.w"
void Parser__Assertions__subject_of_discussion_a_list(void) {
subject_seems_to_be_plural = TRUE;
}
#line 39 "inform7/Chapter 8/To Be and To Have.w"
sentence_handler ASSERT_SH_handler = { SENTENCE_NT, ASSERT_VB, 0, to_be };
void to_be(parse_node *pv) {
parse_node *px = pv->down->next;
parse_node *py = pv->down->next->next;
if ((px->word_ref1 >= 0) && (px->word_ref2 > px->word_ref1)
&& (Text__Vocabulary__test_flags(px->word_ref1, TEXT_MC+TEXTWITHSUBS_MC))) {
Problems__sentence_problem(_P_(C8TextNotClosing),
"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;
}
Parser__Assertions__make_assertion(px, py);
}
#line 74 "inform7/Chapter 8/To Be and To Have.w"
sentence_handler HAS_SH_handler = { SENTENCE_NT, HAS_VB, 0, to_have };
void to_have(parse_node *pv) {
parse_node *px = pv->down->next;
parse_node *py = pv->down->next->next;
{
#line 96 "inform7/Chapter 8/To Be and To Have.w"
if (Parser__Nodes__type(py) == X_OF_Y_NT) {
Problems__sentence_problem(_P_(C8SuperfluousOf),
"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 (Parser__Nodes__type(py) == WITH_NT) {
Problems__sentence_problem(_P_(C8SuperfluousWith),
"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 80 "inform7/Chapter 8/To Be and To Have.w"
;
if (Parser__Nodes__type(py) == CALLED_NT)
{
#line 119 "inform7/Chapter 8/To Be and To Have.w"
if (Text__compare_word_range(py->down->next->word_ref1, py->down->next->word_ref2,
py->down->word_ref1, py->down->word_ref2)) {
Problems__sentence_problem(_P_(C8SuperfluousCalled),
"'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 {
Parser__Nodes__set_node_type(py, PROPERTYCALLED_NT);
if (Parser__Nodes__type(py->down) == AND_NT) {
int L = Parser__Nodes__left_edge_of(py->down),
R = Parser__Nodes__right_edge_of(py->down);
parse_nt_against_word_range(nounphrase_articled_NTM, 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 = Parser__Nodes__new(ALLOWED_NT);
px->next->down = py;
int prohibited = parse_nt_against_word_range(prohibited_property_owners_NTM, px->word_ref1, px->word_ref2, NULL, NULL);
if (!prohibited) {
parse_nt_against_word_range(nounphrase_articled_list_NTM, py->down->next->word_ref1, py->down->next->word_ref2, NULL, NULL);
py->down->next = most_recent_result_p;
}
}
py = px->next;
}
#line 83 "inform7/Chapter 8/To Be and To Have.w"
else if (parse_nt_against_word_range(k_kind_NTM, py->word_ref1, py->word_ref2, NULL, NULL))
{
#line 157 "inform7/Chapter 8/To Be and To Have.w"
px->next = Parser__Nodes__new(ALLOWED_NT);
px->next->down = py;
py = px->next;
}
#line 85 "inform7/Chapter 8/To Be and To Have.w"
else
{
#line 165 "inform7/Chapter 8/To Be and To Have.w"
Parser__Nodes__set_node_type(py, PROPERTY_LIST_NT);
}
#line 87 "inform7/Chapter 8/To Be and To Have.w"
;
Parser__Nodes__annotate_int(pv->down, verb_id_ANNOT, ASSERT_VB);
to_be(pv); /* and start again as if it had been |ASSERT_VB| all along */
}
#line 186 "inform7/Chapter 8/To Be and To Have.w"
void Parser__Assertions__make_assertion(parse_node *px, parse_node *py) {
if (traverse == 1) {
int pc = problem_count;
if (!(parse_nt_against_word_range(s_existential_np_NTM, px->word_ref1, px->word_ref2, NULL, NULL)))
Parser__Nodes__refine(px, ALLOW_CREATION);
Parser__Nodes__refine(py, ALLOW_CREATION);
if (problem_count > pc) return;
if (Parser__Assertions__consult_the_creator(px, py) == FALSE) return;
}
if (trace_sentences) Parser__Nodes__log_subtree(current_sentence, 1);
if (parse_nt_against_word_range(s_existential_np_NTM, px->word_ref1, px->word_ref2, NULL, NULL)) {
if (traverse == 1) {
parse_node *pcn = py;
if (Parser__Nodes__type(pcn) == WITH_NT) pcn = pcn->down;
if (Parser__Nodes__type(pcn) == COMMON_NOUN_NT) {
if (World__Subjects__is_a_kind_of_object(Parser__Nodes__get_subject(pcn)))
Parser__Assertions__convert_instance_to_nounphrase(pcn, NULL);
else {
Problems__sentence_problem(_P_(C8ThereIsVague),
"'there is...' can only be used to create objects",
"and not instances of other kinds.'");
}
}
}
px = py;
} else {
Parser__Assertions__make_assertion_recursive(px, py);
}
{
#line 233 "inform7/Chapter 8/To Be and To Have.w"
inference_subject *infsx = NULL, *infsy = NULL, *infsy_full = NULL;
infsx = discussed_at_node(px);
infsy_full = discussed_at_node(py);
if (Parser__Nodes__type(py) != KIND_NT) infsy = Parser__Nodes__get_subject(py);
Parser__Assertions__change_discussion_topic(infsx, infsy, infsy_full);
if (Parser__Nodes__type(px) == AND_NT) Parser__Assertions__subject_of_discussion_a_list();
if (Parser__Nodes__int_annotation(current_sentence, clears_pronouns_ANNOT))
Parser__Assertions__new_discussion();
}
#line 215 "inform7/Chapter 8/To Be and To Have.w"
;
}
#line 245 "inform7/Chapter 8/To Be and To Have.w"
inference_subject *discussed_at_node(parse_node *pn) {
inference_subject *infs = NULL;
if (Parser__Nodes__type(pn) != KIND_NT) infs = Parser__Nodes__get_subject(pn);
if ((Parser__Nodes__type(pn) == RELATIONSHIP_NT) && (pn->down) &&
(Parser__Nodes__type(pn->down) == PROPER_NOUN_NT))
infs = Parser__Nodes__get_subject(pn->down);
if ((Parser__Nodes__type(pn) == WITH_NT) && (pn->down) &&
(Parser__Nodes__type(pn->down) == PROPER_NOUN_NT))
infs = Parser__Nodes__get_subject(pn->down);
return infs;
}
#line 34 "inform7/Chapter 8/Refine Parse Tree.w"
void Parser__Nodes__noun_from_infs(parse_node *p, inference_subject *infs) {
pn_make_COMMON_or_PROPER(p, infs);
Parser__Nodes__set_evaluation(p, World__Subjects__as_constant(infs));
}
void Parser__Nodes__noun_from_value(parse_node *p, specification *spec) {
inference_subject *infs = NULL;
if (Specifications__get_proposition(spec)) {
kind *K = Calculus__Variables__kind_of_variable_0(
Specifications__get_proposition(spec));
if (Kinds__lt(K, K_object) == FALSE) K = K_object;
infs = Kinds__as_subject(K);
pn_noun_details_from_spec(p, spec);
} else infs = World__Subjects__from_specification(spec);
if ((infs == NULL) && (Specifications__is_generic(spec)))
Parser__Nodes__set_node_type(p, COMMON_NOUN_NT);
else pn_make_COMMON_or_PROPER(p, infs);
Parser__Nodes__set_evaluation(p, spec);
}
#line 63 "inform7/Chapter 8/Refine Parse Tree.w"
void pn_noun_details_from_spec(parse_node *p, specification *spec) {
Parser__Nodes__set_creation_proposition(p, Calculus__Propositions__from_spec(spec, FALSE));
int N = Specifications__Conditions__get_quantification_parameter(spec);
if (N > 0) Parser__Nodes__annotate_int(p, multiplicity_ANNOT, N);
}
#line 81 "inform7/Chapter 8/Refine Parse Tree.w"
void pn_make_COMMON_or_PROPER(parse_node *p, inference_subject *infs) {
Parser__Nodes__set_subject(p, infs);
if ((infs) && (World__Subjects__domain(infs))) Parser__Nodes__set_node_type(p, COMMON_NOUN_NT);
else Parser__Nodes__set_node_type(p, PROPER_NOUN_NT);
}
#line 93 "inform7/Chapter 8/Refine Parse Tree.w"
void Parser__Nodes__copy_noun_details(parse_node *to, parse_node *from) {
Parser__Nodes__set_node_type(to, Parser__Nodes__type(from));
Parser__Nodes__set_evaluation(to, Parser__Nodes__get_evaluation(from));
Parser__Nodes__set_creation_proposition(to, Parser__Nodes__get_creation_proposition(from));
Parser__Nodes__set_subject(to, Parser__Nodes__get_subject(from));
Parser__Nodes__annotate_int(to, multiplicity_ANNOT, Parser__Nodes__int_annotation(from, multiplicity_ANNOT));
Parser__Nodes__annotate_int(to, nowhere_ANNOT, Parser__Nodes__int_annotation(from, nowhere_ANNOT));
}
#line 114 "inform7/Chapter 8/Refine Parse Tree.w"
void pn_make_adjective(parse_node *p, adjective_list_entry *ale, specification *spec) {
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(ale);
Parser__Nodes__set_node_type(p, ADJECTIVE_NT);
Parser__Nodes__set_aph(p, aph);
Parser__Nodes__set_evaluation(p, NULL);
pn_noun_details_from_spec(p, spec);
if (Specifications__Conditions__adjective_used_positively(ale)) Parser__Nodes__annotate_int(p, negated_boolean_ANNOT, FALSE);
else Parser__Nodes__annotate_int(p, negated_boolean_ANNOT, TRUE);
}
#line 128 "inform7/Chapter 8/Refine Parse Tree.w"
void Parser__Nodes__coerce_adjectival_usage_to_noun(parse_node *leaf) {
if ((leaf) && (Parser__Nodes__type(leaf) == ADJECTIVE_NT)) {
instance *q = Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(Parser__Nodes__get_aph(leaf));
if (q) Parser__Nodes__noun_from_value(leaf, Specifications__Values__new_named_CONSTANT(q));
}
}
#line 147 "inform7/Chapter 8/Refine Parse Tree.w"
int forbid_nowhere = FALSE;
void Parser__Nodes__refine(parse_node *p, int creation_rule) {
if (p == NULL) internal_error("Refine parse tree on null pn");
if (Parser__Nodes__int_annotation(p, resolved_ANNOT)) return;
Parser__Nodes__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;
refine_parse_tree_inner(p, creation_rule);
LOG_OUTDENT;
LOGIF(NOUN_RESOLUTION, "Refined subtree is:\n$T", p);
}
#line 168 "inform7/Chapter 8/Refine Parse Tree.w"
void refine_parse_tree_inner(parse_node *p, int creation_rule) {
switch(Parser__Nodes__type(p)) {
case X_OF_Y_NT:
{
#line 185 "inform7/Chapter 8/Refine Parse Tree.w"
Parser__Nodes__refine(p->down, creation_rule);
Parser__Nodes__refine(p->down->next, FORBID_CREATION);
}
#line 170 "inform7/Chapter 8/Refine Parse Tree.w"
; return;
case WITH_NT:
{
#line 196 "inform7/Chapter 8/Refine Parse Tree.w"
Parser__Nodes__refine(p->down, creation_rule);
perform_with_surgery(p);
if (Parser__Nodes__type(p) == WITH_NT) {
int a1 = p->down->word_ref1, a2 = p->down->next->word_ref2;
if ((a1>=0) && (a2>=a1)) {
if (parse_nt_against_word_range(action_pattern_NTM, a1, a2, NULL, NULL)) {
Parser__Nodes__set_action_meaning(p, most_recent_result_p);
Parser__Nodes__set_node_type(p, ACTION_NT);
p->word_ref1 = a1; p->word_ref2 = a2; p->down = NULL;
}
}
}
if (Parser__Nodes__int_annotation(p, resolved_ANNOT) == FALSE)
{
#line 213 "inform7/Chapter 8/Refine Parse Tree.w"
Parser__Nodes__annotate_int(p, resolved_ANNOT, FALSE);
Parser__Nodes__refine(p, creation_rule);
return;
}
#line 208 "inform7/Chapter 8/Refine Parse Tree.w"
;
}
#line 171 "inform7/Chapter 8/Refine Parse Tree.w"
; return;
case AND_NT:
{
#line 220 "inform7/Chapter 8/Refine Parse Tree.w"
Parser__Nodes__refine(p->down, creation_rule);
Parser__Nodes__refine(p->down->next, creation_rule);
perform_and_surgery(p);
}
#line 172 "inform7/Chapter 8/Refine Parse Tree.w"
; return;
case RELATIONSHIP_NT:
{
#line 262 "inform7/Chapter 8/Refine Parse Tree.w"
perform_location_surgery(p);
if (Parser__Nodes__type(p) == AND_NT)
{
#line 213 "inform7/Chapter 8/Refine Parse Tree.w"
Parser__Nodes__annotate_int(p, resolved_ANNOT, FALSE);
Parser__Nodes__refine(p, creation_rule);
return;
}
#line 263 "inform7/Chapter 8/Refine Parse Tree.w"
;
if (p->down) {
Parser__Nodes__refine(p->down, creation_rule);
binary_predicate *bp = Parser__Nodes__get_relationship(p);
if (bp) {
instance *dir = Plugins__Map__get_mapping_direction(Semantics__BPs__get_reversal(bp));
if (dir)
{
#line 281 "inform7/Chapter 8/Refine Parse Tree.w"
LOGIF(NOUN_RESOLUTION, "Directional predicate with BP %s ($O)\n",
Semantics__BPs__get_log_name(bp), dir);
Parser__Nodes__annotate_int(p, relationship_node_type_ANNOT, DIRECTION_RELN);
int d1, d2;
Data__Instances__get_name(dir, &d1, &d2, FALSE);
p->down->next = Parser__Sentences__NPs__new_raw(d1, d2);
Parser__Nodes__noun_from_infs(p->down->next, Data__Instances__as_subject(dir));
Parser__Nodes__annotate_int(p->down->next, resolved_ANNOT, TRUE);
}
#line 270 "inform7/Chapter 8/Refine Parse Tree.w"
;
}
if (p->down->next) Parser__Nodes__refine(p->down->next, creation_rule);
}
}
#line 173 "inform7/Chapter 8/Refine Parse Tree.w"
; return;
case CALLED_NT:
{
#line 235 "inform7/Chapter 8/Refine Parse Tree.w"
if ((Parser__Nodes__type(p->down) == RELATIONSHIP_NT) && (p->down->down)) {
perform_called_surgery(p);
{
#line 213 "inform7/Chapter 8/Refine Parse Tree.w"
Parser__Nodes__annotate_int(p, resolved_ANNOT, FALSE);
Parser__Nodes__refine(p, creation_rule);
return;
}
#line 237 "inform7/Chapter 8/Refine Parse Tree.w"
;
}
Parser__Nodes__refine(p->down, FORBID_CREATION);
if (Parser__Nodes__int_annotation(p->down, multiplicity_ANNOT) > 1) {
Problems__sentence_problem(_P_(C8MultipleCalled),
"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__sentence_problem(_P_(BelievedImpossible),
"'called' can't be used in this context",
"and is best reserved for full sentences.");
else Parser__Nodes__refine(p->down->next, MANDATE_CREATION);
forbid_nowhere = FALSE;
}
#line 174 "inform7/Chapter 8/Refine Parse Tree.w"
; return;
case KIND_NT:
{
#line 297 "inform7/Chapter 8/Refine Parse Tree.w"
inference_subject *kind_of_what = Kinds__as_subject(K_object);
if (p->down) {
parse_node *what = p->down;
if (parse_nt_against_word_range(kind_alias_syntax_NTM, what->word_ref1, what->word_ref2, NULL, NULL)) {
if (most_recent_result) {
LOG("Warning: kind aliasing is disabled for now\n");
/* Parser__Nodes__set_stored_as_kind(p, most_recent_result_p); */
}
}
Parser__Nodes__refine(what, FORBID_CREATION);
kind_of_what = Parser__Nodes__get_subject(what);
}
if ((kind_of_what == NULL) || (World__Subjects__domain(kind_of_what) == NULL))
{
#line 337 "inform7/Chapter 8/Refine Parse Tree.w"
if ((World__Subjects__is_an_object(kind_of_what)) ||
(World__Subjects__is_a_kind_of_object(kind_of_what))) {
Problems__sentence_problem(_P_(C8KindOfInstance),
"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__as_subject(K_object);
} else {
Problems__sentence_problem(_P_(C8KindOfActualValue),
"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__as_subject(K_value);
}
}
#line 310 "inform7/Chapter 8/Refine Parse Tree.w"
;
if ((Parser__Nodes__get_stored_as_kind(p) == NULL) &&
(World__Subjects__as_nonobject_kind(kind_of_what)) &&
(kind_of_what != Kinds__as_subject(K_value)) &&
(kind_of_what != Kinds__as_subject(K_object)))
{
#line 356 "inform7/Chapter 8/Refine Parse Tree.w"
Problems__sentence_problem(_P_(C8KindOfExotica),
"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__as_subject(K_value);
}
#line 315 "inform7/Chapter 8/Refine Parse Tree.w"
;
Parser__Nodes__set_subject(p, kind_of_what);
}
#line 175 "inform7/Chapter 8/Refine Parse Tree.w"
; return;
case PROPER_NOUN_NT:
{
#line 371 "inform7/Chapter 8/Refine Parse Tree.w"
{
#line 389 "inform7/Chapter 8/Refine Parse Tree.w"
if (Parser__Nodes__int_annotation(p, implicitly_refers_to_ANNOT)) {
Config__Plugins__Call__refine_implicit_noun(p);
return;
}
if ((p->word_ref1 < 0) || (p->word_ref1 > p->word_ref2)) {
Parser__Nodes__log_subtree(current_sentence, 1);
internal_error("Tried to resolve malformed noun-phrase");
}
}
#line 371 "inform7/Chapter 8/Refine Parse Tree.w"
;
{
#line 411 "inform7/Chapter 8/Refine Parse Tree.w"
property *prn = NULL;
int p1 = -1, p2 = -1, o1 = -1, o2 = -1;
if (parse_nt_against_word_range(newfound_property_of_NTM, p->word_ref1, p->word_ref2, NULL, NULL)) {
prn = most_recent_result_p;
GET_RW(newfound_property_of_NTM, 1, p1, p2);
GET_RW(newfound_property_of_NTM, 2, o1, o2);
}
if ((prn) && (Properties__Valued__coincides_with_kind(prn))) {
LOGIF(NOUN_RESOLUTION, "Resolving new-property of: $Y\n", prn);
Parser__Nodes__set_node_type(p, X_OF_Y_NT);
parse_nt_against_word_range(nounphrase_articled_NTM, o1, o2, NULL, NULL);
p->down = most_recent_result_p;
parse_nt_against_word_range(nounphrase_as_object_NTM, p1, p2, NULL, NULL);
p->down->next = most_recent_result_p;
Parser__Nodes__annotate_int(p, resolved_ANNOT, FALSE);
LOGIF(NOUN_RESOLUTION, "Resolved new-property to:\n$T\n", p);
Parser__Nodes__refine(p, creation_rule);
return;
}
}
#line 372 "inform7/Chapter 8/Refine Parse Tree.w"
;
{
#line 435 "inform7/Chapter 8/Refine Parse Tree.w"
if (Parser__Nodes__int_annotation(p, nounphrase_article_ANNOT) == IT_ART) {
if ((parse_nt_against_word_range(nominative_pronoun_NTM, p->word_ref1, p->word_ref2, NULL, NULL)) &&
(most_recent_result == 2) &&
(Parser__Assertions__get_current_subject_plurality())) {
Problems__sentence_problem(_P_(C8EnigmaticThey),
"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 (Parser__Assertions__get_current_object() == NULL) {
Problems__sentence_problem(_P_(C8EnigmaticPronoun),
"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 = Parser__Assertions__get_current_object();
if (referent) Parser__Nodes__noun_from_infs(p, referent);
LOGIF(PRONOUNS, "Interpreting 'it' as $j\n$P", referent, current_sentence);
return;
}
}
#line 373 "inform7/Chapter 8/Refine Parse Tree.w"
;
if (forbid_nowhere == FALSE)
{
#line 465 "inform7/Chapter 8/Refine Parse Tree.w"
if (Config__Plugins__Call__act_on_special_NPs(p)) return;
}
#line 374 "inform7/Chapter 8/Refine Parse Tree.w"
;
if (creation_rule != MANDATE_CREATION)
{
#line 470 "inform7/Chapter 8/Refine Parse Tree.w"
specification *spec = NULL;
{
#line 489 "inform7/Chapter 8/Refine Parse Tree.w"
if (parse_nt_against_word_range(value_property_name_NTM, p->word_ref1, p->word_ref2, NULL, NULL))
spec = Properties__to_specification(most_recent_result_p);
}
#line 471 "inform7/Chapter 8/Refine Parse Tree.w"
;
if (spec == NULL)
{
#line 521 "inform7/Chapter 8/Refine Parse Tree.w"
int t1 = p->word_ref1, t2 = p->word_ref2;
if (parse_nt_against_word_range(assertion_np_as_value_NTM, t1, t2, NULL, NULL)) {
if (most_recent_result == FALSE) return;
spec = most_recent_result_p;
} else {
spec = Specifications__Unknown__new(t1, t2);
}
if (Specifications__Conditions__get_quantifier(spec))
{
#line 540 "inform7/Chapter 8/Refine Parse Tree.w"
if (Semantics__Quantifiers__can_be_used_in_assertions(Specifications__Conditions__get_quantifier(spec)) == FALSE) {
Problems__sentence_problem(_P_(C8ComplexDeterminer),
"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 (Specifications__Conditions__get_quantifier(spec) == for_all_quantifier) {
kind *K = Specifications__Conditions__get_described_kind(spec);
if ((K) &&
(Specifications__Conditions__get_described_instance(spec) == NULL) &&
(Specifications__Conditions__number_of_adjectives_applied_to(spec) == 0)) {
Parser__Nodes__set_subject(p, Kinds__as_subject(K));
Parser__Nodes__set_node_type(p, EVERY_NT);
return;
}
Problems__sentence_problem(_P_(C8ComplexEvery),
"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 529 "inform7/Chapter 8/Refine Parse Tree.w"
;
LOGIF(NOUN_RESOLUTION, "Noun phrase $W parsed as value: $S\n", t1, t2, spec);
}
#line 472 "inform7/Chapter 8/Refine Parse Tree.w"
;
if ((Specifications__species_is(spec, NONLOCAL_VARIABLE_SPC)) ||
(Specifications__species_is(spec, CONSTANT_SPC))) {
Parser__Nodes__noun_from_value(p, spec);
return;
}
if (Specifications__species_is(spec, DESCRIPTION_SPC))
{
#line 598 "inform7/Chapter 8/Refine Parse Tree.w"
Parser__Nodes__set_subject(p, NULL);
if (Specifications__get_proposition(spec))
{
#line 606 "inform7/Chapter 8/Refine Parse Tree.w"
Parser__Nodes__noun_from_value(p, spec);
return;
}
#line 599 "inform7/Chapter 8/Refine Parse Tree.w"
else
{
#line 649 "inform7/Chapter 8/Refine Parse Tree.w"
int ignore = FALSE;
if (Specifications__Conditions__get_described_instance(spec)) {
if ((Specifications__Conditions__number_of_adjectives_applied_to(spec) > 0) ||
(Parser__Nodes__int_annotation(p, nounphrase_article_ANNOT) != DEF_ART)) ignore = TRUE;
}
if (ignore == FALSE) {
Parser__Nodes__refine_from_docket(p, spec);
return;
}
}
#line 600 "inform7/Chapter 8/Refine Parse Tree.w"
;
}
#line 479 "inform7/Chapter 8/Refine Parse Tree.w"
;
{
#line 581 "inform7/Chapter 8/Refine Parse Tree.w"
if (Parser__Nodes__int_annotation(p, nounphrase_article_ANNOT) == NO_ART) {
if (parse_nt_against_word_range(action_pattern_NTM, p->word_ref1, p->word_ref2, NULL, NULL)) {
Parser__Nodes__set_action_meaning(p, most_recent_result_p);
Parser__Nodes__set_node_type(p, ACTION_NT);
return;
}
}
}
#line 480 "inform7/Chapter 8/Refine Parse Tree.w"
;
}
#line 377 "inform7/Chapter 8/Refine Parse Tree.w"
;
if (creation_rule != FORBID_CREATION) Parser__Nodes__set_node_type(p, CREATED_NT);
else Parser__Nodes__set_subject(p, NULL);
}
#line 176 "inform7/Chapter 8/Refine Parse Tree.w"
; return;
}
}
#line 322 "inform7/Chapter 8/Refine Parse Tree.w"
int kind_alias_syntax_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 329 "inform7/Chapter 8/Refine Parse Tree.w"
*X = FALSE;
Problems__sentence_problem(_P_(C8UnknownStoredAs),
"what comes after 'stored as' must be the name of a kind already existing",
"and I don't think it is.");
}
#line 324 "inform7/Chapter 8/Refine Parse Tree.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 325 "inform7/Chapter 8/Refine Parse Tree.w"
#line 405 "inform7/Chapter 8/Refine Parse Tree.w"
int newfound_property_of_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 407 "inform7/Chapter 8/Refine Parse Tree.w"
#line 512 "inform7/Chapter 8/Refine Parse Tree.w"
int assertion_np_as_value_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 495 "inform7/Chapter 8/Refine Parse Tree.w"
*X = FALSE;
Problems__sentence_problem(_P_(C8VagueVariable),
"'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 513 "inform7/Chapter 8/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 517 "inform7/Chapter 8/Refine Parse Tree.w"
#line 670 "inform7/Chapter 8/Refine Parse Tree.w"
void Parser__Nodes__refine_from_docket(parse_node *p, specification *spec) {
inference_subject *head = NULL;
{
#line 690 "inform7/Chapter 8/Refine Parse Tree.w"
if (Specifications__Conditions__get_described_kind(spec))
head = Kinds__as_subject(Specifications__Conditions__get_described_kind(spec));
if (Specifications__Conditions__get_described_instance(spec))
head = Data__Instances__as_subject(Specifications__Conditions__get_described_instance(spec));
if (head) {
Parser__Nodes__noun_from_infs(p, head);
pn_noun_details_from_spec(p, spec);
}
}
#line 672 "inform7/Chapter 8/Refine Parse Tree.w"
;
if (Specifications__Conditions__number_of_adjectives_applied_to(spec) > 0) {
if (head)
{
#line 704 "inform7/Chapter 8/Refine Parse Tree.w"
parse_node *lower_copy = Parser__Nodes__new(PROPER_NOUN_NT);
Parser__Nodes__copy(lower_copy, p);
Parser__Nodes__set_node_type(p, WITH_NT);
p->down = lower_copy;
lower_copy->next = Parser__Nodes__new(PROPER_NOUN_NT);
p = lower_copy->next;
}
#line 674 "inform7/Chapter 8/Refine Parse Tree.w"
;
{
#line 719 "inform7/Chapter 8/Refine Parse Tree.w"
int adjectives_in_docket = Specifications__Conditions__number_of_adjectives_applied_to(spec);
if (adjectives_in_docket == 1) {
pn_make_adjective(p, Specifications__Conditions__first_adjective_list_entry(spec), spec);
} else {
Parser__Nodes__set_node_type(p, AND_NT);
adjective_list_entry *ale;
int i = 0;
parse_node *AND_p = p;
LOOP_THROUGH_ADJECTIVE_LIST(ale, spec) {
i++;
parse_node *p3 = Parser__Nodes__new(ADJECTIVE_NT);
pn_make_adjective(p3, ale, spec);
if (i < adjectives_in_docket) {
AND_p->down = p3;
if (i+1 < adjectives_in_docket) {
p3->next = Parser__Nodes__new(AND_NT);
AND_p = p3->next;
}
} else {
AND_p->down->next = p3;
}
}
}
}
#line 675 "inform7/Chapter 8/Refine Parse Tree.w"
;
}
}
#line 791 "inform7/Chapter 8/Refine Parse Tree.w"
void perform_and_surgery(parse_node *p) {
parse_node *x, *a_p, *w_p, *p1_p, *p2_p, *i_p;
if ((Parser__Nodes__type(p->down) == ADJECTIVE_NT)
&& (Parser__Nodes__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;
Parser__Nodes__set_node_type(a_p, WITH_NT);
Parser__Nodes__set_node_type(w_p, AND_NT);
Parser__Nodes__set_subject(a_p, Parser__Nodes__get_subject(w_p));
Parser__Nodes__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 838 "inform7/Chapter 8/Refine Parse Tree.w"
void perform_with_surgery(parse_node *p) {
parse_node *inst, *prop_1, *prop_2;
if ((Parser__Nodes__type(p) == WITH_NT) && (Parser__Nodes__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 = Parser__Nodes__new(AND_NT);
p->down->next->down = prop_1;
p->down->next->down->next = prop_2;
}
}
#line 871 "inform7/Chapter 8/Refine Parse Tree.w"
void perform_location_surgery(parse_node *p) {
parse_node *old_and, *old_np1, *old_loc2;
if ((Parser__Nodes__type(p) == RELATIONSHIP_NT) &&
(p->down) && (Parser__Nodes__type(p->down) == AND_NT) &&
(p->down->down) && (p->down->down->next) &&
(Parser__Nodes__type(p->down->down->next) == RELATIONSHIP_NT)) {
Parser__Nodes__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;
Parser__Nodes__copy(old_and, p); /* making this the new first location node */
Parser__Nodes__set_node_type(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 910 "inform7/Chapter 8/Refine Parse Tree.w"
void 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 */
Parser__Nodes__set_node_type(p, RELATIONSHIP_NT);
Parser__Nodes__annotate_int(p, relationship_node_type_ANNOT,
Parser__Nodes__int_annotation(p->down, relationship_node_type_ANNOT));
Parser__Nodes__set_node_type(p->down, CALLED_NT);
p->down->next = x_pn;
p->down->down->next = name_pn;
}
#line 36 "inform7/Chapter 8/The Creator.w"
int problem_count_when_creator_started;
int Parser__Assertions__consult_the_creator(parse_node *px, parse_node *py) {
problem_count_when_creator_started = problem_count;
if (parse_nt_against_word_range(s_existential_np_NTM, px->word_ref1, px->word_ref2, NULL, NULL))
{
#line 60 "inform7/Chapter 8/The Creator.w"
noun_creator(py, NULL, NULL);
}
#line 41 "inform7/Chapter 8/The Creator.w"
else
{
#line 76 "inform7/Chapter 8/The Creator.w"
{
#line 102 "inform7/Chapter 8/The Creator.w"
if ((Parser__Nodes__type(px) == ACTION_NT) && (Parser__Nodes__type(py) == CREATED_NT))
Parser__Nodes__set_node_type(py, ACTION_NT);
if ((Parser__Nodes__type(px) == ACTION_NT) && (Parser__Nodes__type(py) == KIND_NT))
Parser__Nodes__set_node_type(px, CREATED_NT);
}
#line 76 "inform7/Chapter 8/The Creator.w"
;
parse_node *govx = NULL, *govy = NULL;
kind *kindx = NULL, *kindy = NULL;
{
#line 130 "inform7/Chapter 8/The Creator.w"
binary_predicate *bp = bp_of_subtree(py);
if (bp == NULL) bp = bp_of_subtree(px);
if (bp) {
kindx = Kinds__weaken(Semantics__BPs__term_kind(bp, 0));
kindy = Kinds__weaken(Semantics__BPs__term_kind(bp, 1));
if ((bp == R_containment) ||
(Semantics__BPs__get_reversal(bp) == R_containment)) { kindx = K_object; kindy = K_object; }
}
if ((kindx == NULL) || (kindy == NULL)) {
kindx = kind_of_subtree(px, &govx);
kindy = kind_of_subtree(py, &govy);
}
}
#line 79 "inform7/Chapter 8/The Creator.w"
;
noun_creator(px, kindy, govy);
noun_creator(py, kindx, govx);
}
#line 43 "inform7/Chapter 8/The Creator.w"
;
if (problem_count > problem_count_when_creator_started) return FALSE;
return TRUE;
}
#line 146 "inform7/Chapter 8/The Creator.w"
binary_predicate *bp_of_subtree(parse_node *p) {
if ((p) && (Parser__Nodes__type(p) == RELATIONSHIP_NT)) return Parser__Nodes__get_relationship(p);
return NULL;
}
#line 154 "inform7/Chapter 8/The Creator.w"
kind *kind_of_subtree(parse_node *p, parse_node **governing) {
if (p == NULL) return NULL;
switch (Parser__Nodes__type(p)) {
case AND_NT:
{
#line 174 "inform7/Chapter 8/The Creator.w"
kind *left = kind_of_subtree(p->down, governing);
kind *right = kind_of_subtree(p->down->next, governing);
if (left) return left;
return right;
}
#line 157 "inform7/Chapter 8/The Creator.w"
;
case WITH_NT: return kind_of_subtree(p->down, governing); /* the owner, not the property */
case KIND_NT:
{
#line 183 "inform7/Chapter 8/The Creator.w"
*governing = p;
return World__Subjects__domain(Parser__Nodes__get_subject(p));
}
#line 159 "inform7/Chapter 8/The Creator.w"
;
default: {
specification *spec = Parser__Nodes__get_evaluation(p);
{
#line 189 "inform7/Chapter 8/The Creator.w"
if ((Specifications__Storage__is_generic_NONLOCAL_VARIABLE(spec)) ||
(Specifications__Values__is_generic_CONSTANT(spec))) {
kind *found = Specifications__evaluates_to(spec);
if (found) {
*governing = p;
if (Kinds__le(found, K_object)) return K_object;
}
return found;
}
}
#line 162 "inform7/Chapter 8/The Creator.w"
;
{
#line 202 "inform7/Chapter 8/The Creator.w"
if ((prevailing_mood == INITIALLY_CE) || (prevailing_mood == CERTAIN_CE)) {
if ((Specifications__Values__is_actual_CONSTANT(spec)) ||
(Specifications__Storage__is_constant_NONLOCAL_VARIABLE(spec))) {
*governing = p;
return Kinds__weaken(Specifications__evaluates_to(spec));
}
}
}
#line 163 "inform7/Chapter 8/The Creator.w"
;
{
#line 224 "inform7/Chapter 8/The Creator.w"
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
*governing = p;
return Specifications__get_kind_referred_to(spec);
}
}
#line 164 "inform7/Chapter 8/The Creator.w"
;
{
#line 213 "inform7/Chapter 8/The Creator.w"
if (Specifications__Values__is_actual_CONSTANT_construction(spec, CON_property)) {
property *prn = Properties__from_specification(spec);
if ((Properties__is_either_or(prn) == FALSE) &&
(Properties__Valued__coincides_with_kind(prn)))
return Properties__Valued__kind(prn);
}
}
#line 165 "inform7/Chapter 8/The Creator.w"
;
}
}
return NULL;
}
#line 252 "inform7/Chapter 8/The Creator.w"
void noun_creator(parse_node *p, kind *create_as, parse_node *governor) {
switch (Parser__Nodes__type(p)) {
case CALLED_NT:
{
#line 278 "inform7/Chapter 8/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 ((Parser__Nodes__type(what_to_make_node) != COMMON_NOUN_NT) &&
(Parser__Nodes__type(what_to_make_node) != WITH_NT)) {
{
#line 335 "inform7/Chapter 8/The Creator.w"
Problems__sentence_problem(_P_(C8CalledWithoutKind),
"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: */
Parser__Nodes__set_node_type(p, CREATED_NT);
p->word_ref1 = called_name_node->word_ref1; p->word_ref2 = called_name_node->word_ref2;
p->down = NULL;
}
#line 283 "inform7/Chapter 8/The Creator.w"
; return;
}
parse_node *local_governor = NULL;
kind *local_create_as = kind_of_subtree(what_to_make_node, &local_governor);
if (local_create_as == NULL) { local_create_as = create_as; local_governor = governor; }
noun_creator(called_name_node, local_create_as, local_governor);
{
#line 300 "inform7/Chapter 8/The Creator.w"
parse_node *p_sibling = p->next;
Parser__Nodes__copy(p, called_name_node); p->down = NULL; p->next = p_sibling;
inference_subject *new_creation = Parser__Nodes__get_subject(p);
inference_subject *its_domain = Parser__Nodes__get_subject(what_to_make_node);
if ((new_creation) && (its_domain))
Calculus__Propositions__assert_kind_of_subject(new_creation, its_domain,
Specifications__get_proposition(Parser__Nodes__get_evaluation(what_to_make_node)));
if (Parser__Nodes__type(what_to_make_node) == WITH_NT)
Parser__Assertions__assert_property_list(p, what_to_make_node->down->next);
}
#line 291 "inform7/Chapter 8/The Creator.w"
;
{
#line 323 "inform7/Chapter 8/The Creator.w"
if ((Parser__Nodes__type(called_name_node) == PROPER_NOUN_NT) &&
(Parser__Nodes__int_annotation(called_name_node, nounphrase_article_ANNOT) == DEF_ART)) {
inference_subject *subj = Parser__Nodes__get_subject(p);
if ((World__Subjects__is_an_object(subj)) ||
(World__Subjects__is_a_kind_of_object(subj)))
Plugins__Naming__object_takes_definite_article(subj);
}
}
#line 292 "inform7/Chapter 8/The Creator.w"
;
}
#line 254 "inform7/Chapter 8/The Creator.w"
; return;
case CREATED_NT:
{
#line 366 "inform7/Chapter 8/The Creator.w"
int wording1 = p->word_ref1, wording2 = p->word_ref2;
if (wording1 < 0) internal_error("CREATED node without name");
if (parse_nt_against_word_range(grammatical_gender_marker_NTM, wording1, wording2, NULL, NULL)) {
GET_RW(grammatical_gender_marker_NTM, 1, wording1, wording2);
Parser__Nodes__annotate_int(p, gender_reference_ANNOT, -(most_recent_result + 1));
}
{
#line 514 "inform7/Chapter 8/The Creator.w"
if (parse_nt_against_word_range(creation_problem_diagnosis_NTM, wording1, wording2, NULL, NULL)) {
wording1 = -1; wording2 = -1;
}
}
#line 372 "inform7/Chapter 8/The Creator.w"
;
p->word_ref1 = wording1; p->word_ref2 = wording2; /* in case not */
if (((create_as == NULL) || (Kinds__le(create_as, K_object))) &&
(prevailing_mood != INITIALLY_CE) &&
(prevailing_mood != CERTAIN_CE)) {
instance *recent_creation = NULL;
if (wording1 >= 0)
{
#line 542 "inform7/Chapter 8/The Creator.w"
recent_creation = Data__Instances__parse_object(wording1, wording2);
if (recent_creation) {
int w1, w2;
Data__Instances__get_name(recent_creation, &w1, &w2, FALSE);
if ((w1 >= 0) && (Text__compare_word_range(wording1, wording2, w1, w2) == FALSE))
recent_creation = NULL;
}
if (recent_creation == NULL)
{
#line 555 "inform7/Chapter 8/The Creator.w"
int is_a_kind = FALSE;
if ((governor) && (Parser__Nodes__type(governor) == KIND_NT)) is_a_kind = TRUE;
pcalc_prop *prop = Calculus__Propositions__to_create_something(K_object, wording1, wording2);
if (is_a_kind)
prop = Calculus__Propositions__concatenate(prop, Calculus__Propositions__to_make_a_kind(K_object));
Calculus__Propositions__assert_true(prop, CERTAIN_CE);
if (is_a_kind == FALSE) {
recent_creation = latest_instance;
if (Parser__Nodes__int_annotation(p, plural_reference_ANNOT))
Plugins__Naming__object_now_has_plural_name(recent_creation);
if (Parser__Nodes__int_annotation(p, nounphrase_article_ANNOT) == NO_ART)
Plugins__Naming__object_now_has_proper_name(recent_creation);
int g = Parser__Nodes__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,
Data__Instances__as_subject(recent_creation),
Data__Instances__get_value(grammatical_genders[g-1]),
c);
}
} else {
specification *val = Specifications__Values__new_generic_CONSTANT(latest_base_kind_of_value);
Parser__Nodes__noun_from_value(p, val);
}
}
#line 550 "inform7/Chapter 8/The Creator.w"
;
}
#line 378 "inform7/Chapter 8/The Creator.w"
;
if (recent_creation) Parser__Nodes__noun_from_infs(p, Data__Instances__as_subject(recent_creation));
} else {
specification *val = NULL;
if (wording1 >= 0)
{
#line 588 "inform7/Chapter 8/The Creator.w"
specification *governing_spec = Parser__Nodes__get_evaluation(governor);
if ((governor) && (Parser__Nodes__type(governor) == KIND_NT))
{
#line 611 "inform7/Chapter 8/The Creator.w"
pcalc_prop *prop = Calculus__Propositions__to_create_something(NULL, wording1, wording2);
prop = Calculus__Propositions__concatenate(prop, Calculus__Propositions__to_make_a_kind(K_value));
Calculus__Propositions__assert_true(prop, prevailing_mood);
if (Parser__Nodes__get_stored_as_kind(governor))
Kinds__equate_latest(Parser__Nodes__get_stored_as_kind(governor));
val = Specifications__Values__new_generic_CONSTANT(latest_base_kind_of_value);
}
#line 590 "inform7/Chapter 8/The Creator.w"
else if ((Specifications__Storage__is_generic_NONLOCAL_VARIABLE(governing_spec)) ||
(prevailing_mood == INITIALLY_CE) ||
(prevailing_mood == CERTAIN_CE))
{
#line 621 "inform7/Chapter 8/The Creator.w"
kind *domain = Specifications__get_kind(governing_spec);
if (domain == NULL) domain = Kinds__weaken(Specifications__evaluates_to(governing_spec));
if (Kinds__contains(domain, Kinds__get_construct(K_understanding)))
{
#line 670 "inform7/Chapter 8/The Creator.w"
Problems__assertion_problem(_P_(C8NoTopicsThatVary),
"'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 624 "inform7/Chapter 8/The Creator.w"
;
pcalc_prop *prop = Calculus__Propositions__to_create_something(domain, wording1, wording2);
if (prevailing_mood == CERTAIN_CE)
prop = Calculus__Propositions__concatenate(prop, Calculus__Propositions__to_make_a_const());
else
prop = Calculus__Propositions__concatenate(prop, Calculus__Propositions__to_make_a_var());
Calculus__Propositions__assert_true(prop, prevailing_mood);
val = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(latest_nonlocal_variable);
}
#line 594 "inform7/Chapter 8/The Creator.w"
else if (Kinds__get_construct(create_as) == CON_rulebook)
{
#line 648 "inform7/Chapter 8/The Creator.w"
kind *basis = NULL, *producing = NULL;
Kinds__binary_construction_material(create_as, &basis, &producing);
if (Kinds__eq(basis, K_value)) basis = K_action_name;
if (Kinds__eq(producing, K_value)) producing = K_nil;
create_as = Kinds__binary_construction(CON_rulebook, basis, producing);
if (governor)
Parser__Nodes__set_evaluation(governor,
Specifications__Values__new_generic_CONSTANT(create_as));
rulebook *rb = Code__Rulebooks__new(create_as, wording1, wording2);
val = Code__Rulebooks__to_specification(rb);
Parser__Nodes__annotate_int(current_sentence, clears_pronouns_ANNOT, TRUE);
}
#line 596 "inform7/Chapter 8/The Creator.w"
else if (Kinds__get_construct(create_as) == CON_activity)
{
#line 663 "inform7/Chapter 8/The Creator.w"
activity *av = Code__Activities__new(create_as, wording1, wording2);
val = Code__Activities__to_specification(av);
Parser__Nodes__annotate_int(current_sentence, clears_pronouns_ANNOT, TRUE);
}
#line 598 "inform7/Chapter 8/The Creator.w"
else if ((Kinds__definite(create_as)) && (Kinds__is_quasinumerical(create_as)))
{
#line 679 "inform7/Chapter 8/The Creator.w"
Problems__sentence_problem(_P_(C8MixedConstants),
"this is a kind of value which already has a semi-numerical specification",
"so it can't have an entirely verbal form as well.");
}
#line 600 "inform7/Chapter 8/The Creator.w"
else if ((Kinds__definite(create_as)) && (Kinds__has_named_constant_values(create_as)))
{
#line 636 "inform7/Chapter 8/The Creator.w"
pcalc_prop *prop = Calculus__Propositions__to_create_something(create_as, wording1, wording2);
pcalc_prop *such_that = Parser__Nodes__get_creation_proposition(governor);
if (such_that) prop = Calculus__Propositions__concatenate(prop, such_that);
Calculus__Propositions__assert_true(prop, prevailing_mood);
val = Specifications__Values__new_named_CONSTANT(latest_instance);
}
#line 602 "inform7/Chapter 8/The Creator.w"
else
{
#line 687 "inform7/Chapter 8/The Creator.w"
if (problem_count_when_creator_started == problem_count) {
LOG("$W: $u\n$T\n", wording1, wording2, create_as, governor);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, wording1, wording2);
Problems__quote_kind(3, create_as);
Problems__handmade_problem(_P_(C8NoNewInstances));
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 an an alias for a "
"constant value. Some programming languages encourage this, "
"but Inform doesn't: instead, make it a variable and then "
"don't vary it - 'The lucky number is a number that varies. "
"The lucky number is 8.'");
Problems__issue_problem_end();
}
}
#line 604 "inform7/Chapter 8/The Creator.w"
;
Index__DocReferences__position_of_symbol(&wording1, &wording2);
p->word_ref1 = wording1; p->word_ref2 = wording2;
}
#line 382 "inform7/Chapter 8/The Creator.w"
;
Parser__Nodes__noun_from_value(p, val);
}
}
#line 255 "inform7/Chapter 8/The Creator.w"
; return;
}
parse_node *ch;
for (ch = p->down; ch; ch = ch->next) noun_creator(ch, create_as, governor);
}
#line 351 "inform7/Chapter 8/The Creator.w"
int grammatical_gender_marker_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 353 "inform7/Chapter 8/The Creator.w"
int grammatical_gender_abbreviation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 358 "inform7/Chapter 8/The Creator.w"
#line 391 "inform7/Chapter 8/The Creator.w"
int creation_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 405 "inform7/Chapter 8/The Creator.w"
Problems__sentence_problem(_P_(C8NameIsArticle),
"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 392 "inform7/Chapter 8/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 415 "inform7/Chapter 8/The Creator.w"
Problems__sentence_problem(_P_(C8NameWithBrackets),
"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 393 "inform7/Chapter 8/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 426 "inform7/Chapter 8/The Creator.w"
STREAM_WRITE(STDERR, "*** Exit(1) requested for testing purposes ***\n");
STREAM_FLUSH(STDERR);
Problems__sentence_problem(_P_(C8Crash1),
"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 394 "inform7/Chapter 8/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 437 "inform7/Chapter 8/The Creator.w"
STREAM_WRITE(STDERR, "*** Exit(10) requested for testing purposes ***\n");
STREAM_FLUSH(STDERR);
Problems__sentence_problem(_P_(C8Crash10),
"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 395 "inform7/Chapter 8/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 448 "inform7/Chapter 8/The Creator.w"
STREAM_WRITE(STDERR, "*** Exit(11) requested for testing purposes ***\n");
STREAM_FLUSH(STDERR);
Problems__sentence_problem(_P_(C8Crash11),
"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 396 "inform7/Chapter 8/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 459 "inform7/Chapter 8/The Creator.w"
LOG("$T\n", current_sentence);
Problems__sentence_problem(_P_(C8StartsWithComma),
"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 397 "inform7/Chapter 8/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 469 "inform7/Chapter 8/The Creator.w"
Problems__sentence_problem(_P_(C8EndsWithComma),
"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 398 "inform7/Chapter 8/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7:
{
#line 478 "inform7/Chapter 8/The Creator.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C8ObjectIncWhen));
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 399 "inform7/Chapter 8/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8:
{
#line 500 "inform7/Chapter 8/The Creator.w"
Problems__assertion_problem(_P_(C8NameWithText),
"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 400 "inform7/Chapter 8/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 401 "inform7/Chapter 8/The Creator.w"
#line 714 "inform7/Chapter 8/The Creator.w"
int Parser__Assertions__vet_name(int wording1, int wording2) {
if (parse_nt_against_word_range(creation_problem_diagnosis_NTM, wording1, wording2, NULL, NULL)) return FALSE;
return TRUE;
}
#line 740 "inform7/Chapter 8/The Creator.w"
int name_stubs_count = 0;
void Parser__Assertions__convert_instance_to_nounphrase(parse_node *p, binary_predicate *hinge_relation) {
int confect_name_flag = FALSE;
if ((hinge_relation) && (Semantics__BPs__is_the_wrong_way_round(hinge_relation)))
hinge_relation = Semantics__BPs__get_reversal(hinge_relation);
if (hinge_relation == R_incorporation) confect_name_flag = TRUE;
int instance_count;
int mw1 = -1, mw2 = -1, cw1 = -1, cw2 = -1, w1, w2; w1 = p->word_ref1; w2 = p->word_ref2;
if (parse_nt_against_word_range(text_ending_with_a_calling_NTM, w1, w2, NULL, NULL)) {
GET_RW(text_ending_with_a_calling_NTM, 1, mw1, mw2); /* the text before the bracketed clause */
GET_RW(text_ending_with_a_calling_NTM, 2, cw1, cw2); /* the bracketed text */
p->word_ref1 = mw1; p->word_ref2 = mw2;
}
kind *instance_kind = K_object;
if (Specifications__Values__is_generic_CONSTANT(Parser__Nodes__get_evaluation(p)))
instance_kind = Specifications__get_kind(Parser__Nodes__get_evaluation(p));
if ((Kinds__le(instance_kind, K_object) == FALSE) &&
(Kinds__has_named_constant_values(instance_kind) == FALSE))
{
#line 771 "inform7/Chapter 8/The Creator.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, instance_kind);
Problems__handmade_problem(_P_(C8CantCreateImplicitly));
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;
Parser__Nodes__annotate_int(p, multiplicity_ANNOT, 1);
}
#line 759 "inform7/Chapter 8/The Creator.w"
;
{
#line 791 "inform7/Chapter 8/The Creator.w"
instance_count = Parser__Nodes__int_annotation(p, multiplicity_ANNOT);
if (instance_count < 1) instance_count = 1;
if (instance_count > MAX_DUPLICATES_AT_ONCE) {
Problems__assertion_problem(_P_(C8TooManyDuplicates),
"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 760 "inform7/Chapter 8/The Creator.w"
;
parse_node *list_subtree = Parser__Nodes__new(COMMON_NOUN_NT);
parse_node *original_next = p->next;
{
#line 807 "inform7/Chapter 8/The Creator.w"
parse_node *attach_to = list_subtree;
int i;
for (i=1; i<=instance_count; i++) {
inference_subject *new_instance = NULL;
{
#line 826 "inform7/Chapter 8/The Creator.w"
inference_subject *named_after = NULL;
int name1 = -1, name2 = -1, name_after_w1 = -1, name_after_w2 = -1;
int propriety = FALSE;
{
#line 855 "inform7/Chapter 8/The Creator.w"
inference_subject *owner = Parser__Nodes__get_implicit_in_creation_of(current_sentence);
if ((owner) && (instance_count == 1) &&
((confect_name_flag) ||
(Kinds__le(instance_kind, K_object) == FALSE) || (cw1 >= 0))) {
int owner_w1 = -1, owner_w2 = -1;
World__Subjects__get_name_text(owner, &owner_w1, &owner_w2);
inference_subject *subject_here = Parser__Nodes__get_subject(p);
if (subject_here) World__Subjects__get_name_text(subject_here, &name1, &name2);
if ((owner_w1 >= 0) && (name1 >= 0) && (cw1 < 0)) {
cw1 = lexer_wordcount;
char confected_name[32];
sprintf(confected_name, " its ");
Text__feed_into_lexer(confected_name, TRUE, NULL);
Text__splice_words(name1, name2);
cw2 = lexer_wordcount-1;
}
if (cw1 >= 0) {
named_after = owner;
name_after_w1 = name1; name_after_w2 = name2;
int x1 = lexer_wordcount;
int j;
for (j = cw1; j <= cw2; j++) {
if (parse_nt_against_word_range(possessive_third_person_NTM, j, j, NULL, NULL))
{
#line 894 "inform7/Chapter 8/The Creator.w"
char confected_name[MAX_WORD_LENGTH+10];
if (Config__Plugins__Call__irregular_genitive(owner, confected_name, &propriety) == FALSE) {
if (owner_w1 == -1) {
confected_name[0] = 0;
} else {
if (owner_w2 > owner_w1) Text__splice_words(owner_w1, owner_w2-1);
Text__print_raw_text_to_string(owner_w2, owner_w2, confected_name);
if (Platform__strlen(confected_name) < MAX_WORD_LENGTH-3)
sprintf(confected_name+Platform__strlen(confected_name), "'s ");
}
}
Text__feed_into_lexer(confected_name, TRUE, NULL);
}
#line 878 "inform7/Chapter 8/The Creator.w"
else if (parse_nt_against_word_range(pronoun_NTM, j, j, NULL, NULL))
{
#line 910 "inform7/Chapter 8/The Creator.w"
Text__splice_words(owner_w1, owner_w2);
}
#line 880 "inform7/Chapter 8/The Creator.w"
else Text__splice_words(j, j);
}
int x2 = lexer_wordcount-1;
LOGIF(NOUN_RESOLUTION, "Confecting the name: <$W>\n", x1, x2);
name1 = x1; name2 = x2;
} else {
name1 = -1; name2 = -1;
}
}
}
#line 829 "inform7/Chapter 8/The Creator.w"
;
if (Kinds__le(instance_kind, K_object) == FALSE)
{
#line 915 "inform7/Chapter 8/The Creator.w"
int stub_w1 = -1, stub_w2 = -1;
if (name1 == -1) {
World__Subjects__get_name_text(Kinds__as_subject(instance_kind), &stub_w1, &stub_w2);
} else {
if (parse_nt_against_word_range(s_constant_value_NTM, name1, name2, NULL, NULL)) {
stub_w1 = name1; stub_w2 = name2;
}
}
if (stub_w1 >= 0) {
char textual_count[32];
sprintf(textual_count, " %d ", ++name_stubs_count);
name1 = lexer_wordcount;
Text__splice_words(stub_w1, stub_w2);
Text__feed_into_lexer(textual_count, TRUE, NULL);
name2 = lexer_wordcount - 1;
}
}
#line 831 "inform7/Chapter 8/The Creator.w"
;
if (name2 >= name1 + 32) name2 = name1 + 31; /* truncate to the maximum length */
parse_node *pz = Parser__Nodes__new(PROPER_NOUN_NT);
pcalc_prop *prop = Calculus__Propositions__to_create_something(instance_kind, name1, name2);
Calculus__Propositions__assert_true(prop, prevailing_mood);
if (Kinds__le(instance_kind, K_object))
new_instance = Data__Instances__as_subject(latest_instance);
else
new_instance = Data__Instances__as_subject(latest_instance);
if (named_after) {
Plugins__Naming__transfer_details(named_after, new_instance);
Parser__Assertions__Assemblies__name_object_after(new_instance, named_after, name_after_w1, name_after_w2);
if ((World__Subjects__is_an_object(named_after) == FALSE) &&
(World__Subjects__is_a_kind_of_object(named_after) == FALSE)) propriety = TRUE;
}
if (propriety) Plugins__Naming__now_has_proper_name(new_instance);
Parser__Nodes__noun_from_infs(pz, new_instance);
Parser__Assertions__make_assertion_recursive(pz, p);
}
#line 811 "inform7/Chapter 8/The Creator.w"
;
if (i < instance_count) {
Parser__Nodes__set_node_type(attach_to, AND_NT);
attach_to->down = Parser__Nodes__new(PROPER_NOUN_NT);
Parser__Nodes__noun_from_infs(attach_to->down, new_instance);
attach_to->down->next = Parser__Nodes__new(PROPER_NOUN_NT);
attach_to = attach_to->down->next;
} else {
Parser__Nodes__noun_from_infs(attach_to, new_instance);
}
}
}
#line 763 "inform7/Chapter 8/The Creator.w"
;
Parser__Nodes__copy(p, list_subtree);
p->next = original_next;
}
#line 938 "inform7/Chapter 8/The Creator.w"
int text_ending_with_a_calling_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 941 "inform7/Chapter 8/The Creator.w"
int text_including_a_calling_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 944 "inform7/Chapter 8/The Creator.w"
#line 955 "inform7/Chapter 8/The Creator.w"
int unsuitable_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 959 "inform7/Chapter 8/The Creator.w"
int unsuitable_name_for_locals_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 964 "inform7/Chapter 8/The Creator.w"
int unfortunate_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 968 "inform7/Chapter 8/The Creator.w"
#line 972 "inform7/Chapter 8/The Creator.w"
void Parser__Assertions__vet_name_for_noun(int wording1, int wording2) {
if (parse_nt_against_word_range(unfortunate_name_NTM, wording1, wording2, NULL, NULL))
Problems__sentence_problem(_P_(C8NameBestAvoided),
"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.)");
}
#line 46 "inform7/Chapter 8/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 8/Make Assertions.w"
int 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 ((Parser__Nodes__Types__allow_in_assertions(px) == FALSE) ||
(Parser__Nodes__Types__allow_in_assertions(py) == FALSE)) {
Parser__Nodes__log_subtree(px, 1);
Parser__Nodes__log_subtree(py, 1);
internal_error("make assertion with improper nodes");
}
int i, x=-1, y=-1, wx = Parser__Nodes__type(px), wy = Parser__Nodes__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)) {
Parser__Nodes__log_subtree(px, 1);
Parser__Nodes__log_subtree(py, 1);
internal_error("make assertion with node type not in matrix");
}
return assertion_matrix[y].cases[x];
}
#line 91 "inform7/Chapter 8/Make Assertions.w"
void Parser__Assertions__make_assertion_recursive(parse_node *px, parse_node *py) {
LOG_INDENT;
make_assertion_recursive_inner(px, py);
LOG_OUTDENT;
}
void make_assertion_recursive_inner(parse_node *px, parse_node *py) {
{
#line 114 "inform7/Chapter 8/Make Assertions.w"
int pc = problem_count;
if (Config__Plugins__Call__intervene_in_assertion(px, py)) return;
if (problem_count > pc) return;
}
#line 98 "inform7/Chapter 8/Make Assertions.w"
;
if (traverse == 2)
{
#line 121 "inform7/Chapter 8/Make Assertions.w"
if ((prevailing_mood == INITIALLY_CE) &&
((Parser__Nodes__type(px) != PROPER_NOUN_NT) ||
(Parser__Nodes__type(py) != PROPER_NOUN_NT))) {
Problems__sentence_problem(_P_(C8MisplacedInitially),
"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) &&
(Specifications__Values__is_actual_CONSTANT_construction(Parser__Nodes__get_evaluation(px), CON_property) == FALSE) &&
(Specifications__Storage__is_actual_NONLOCAL_VARIABLE(Parser__Nodes__get_evaluation(px)) == FALSE) &&
(Parser__Nodes__type(px) == PROPER_NOUN_NT)) {
Problems__sentence_problem(_P_(C8VagueAboutSpecific),
"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 (((Parser__Nodes__type(px) == COMMON_NOUN_NT)
&& (Parser__Nodes__get_evaluation(px)) && (Parser__Nodes__int_annotation(px, multiplicity_ANNOT) > 1)
&& (Parser__Nodes__type(py) != RELATIONSHIP_NT)) ||
((Parser__Nodes__type(py) == COMMON_NOUN_NT)
&& (Parser__Nodes__get_evaluation(py)) && (Parser__Nodes__int_annotation(py, multiplicity_ANNOT) > 1)
&& (Parser__Nodes__type(px) != RELATIONSHIP_NT))) {
Problems__sentence_problem(_P_(C8MultiplyVague),
"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 99 "inform7/Chapter 8/Make Assertions.w"
;
if (prevailing_mood == INITIALLY_CE) prevailing_mood = LIKELY_CE;
int ma_case = which_assertion_case(px, py);
LOGIF(ASSERTIONS, "[$W/$N] =%d [$W/$N]\n",
px->word_ref1, px->word_ref2, Parser__Nodes__type(px), ma_case,
py->word_ref1, py->word_ref2, Parser__Nodes__type(py));
{
#line 163 "inform7/Chapter 8/Make Assertions.w"
switch(ma_case) {
case 1:
{
#line 213 "inform7/Chapter 8/Make Assertions.w"
parse_node *across = py->down;
int np = problem_count;
while (across) {
if (np == problem_count) Parser__Assertions__make_assertion_recursive(px, across);
across = across->next;
}
}
#line 164 "inform7/Chapter 8/Make Assertions.w"
; return;
case 2:
{
#line 236 "inform7/Chapter 8/Make Assertions.w"
if ((Parser__Nodes__type(px->down) == COMMON_NOUN_NT) &&
(Parser__Nodes__is_adjlist(px->down->next)) &&
(Parser__Nodes__is_adjlist(py))) {
Parser__Assertions__Implications__new(px, py);
} else {
int np = problem_count;
Parser__Assertions__make_assertion_recursive(px->down, py); /* A is B */
if (problem_count == np)
Parser__Assertions__make_assertion_recursive(px->down->next, py); /* I is B */
}
}
#line 165 "inform7/Chapter 8/Make Assertions.w"
; return;
case 3:
{
#line 267 "inform7/Chapter 8/Make Assertions.w"
if ((Parser__Nodes__type(px) == PROPER_NOUN_NT) &&
(Plugins__Map__is_a_direction(Parser__Nodes__get_subject(px))) &&
(Parser__Nodes__type(py->down) == PROPER_NOUN_NT)) {
int np = problem_count;
Parser__Assertions__make_assertion_recursive(px, py->down); /* A is a B */
if (problem_count == np)
Parser__Assertions__make_assertion_recursive(py->down, py->down->next); /* B is I */
} else {
int np = problem_count;
Parser__Assertions__make_assertion_recursive(px, py->down); /* A is a B */
if (problem_count == np)
Parser__Assertions__make_assertion_recursive(px, py->down->next); /* A is I */
}
}
#line 166 "inform7/Chapter 8/Make Assertions.w"
; return;
case 4:
{
#line 286 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8WithIsWith),
"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 167 "inform7/Chapter 8/Make Assertions.w"
; return;
case 5:
{
#line 294 "inform7/Chapter 8/Make Assertions.w"
parse_node *across = px->down;
int np = problem_count;
while (across) {
if (np == problem_count) Parser__Assertions__make_assertion_recursive(across, py);
across = across->next;
}
}
#line 168 "inform7/Chapter 8/Make Assertions.w"
; return;
case 6:
{
#line 305 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8XofYisZofW),
"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 169 "inform7/Chapter 8/Make Assertions.w"
; return;
case 7:
{
#line 316 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8BadXofY),
"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 170 "inform7/Chapter 8/Make Assertions.w"
; return;
case 8:
{
#line 333 "inform7/Chapter 8/Make Assertions.w"
if (traverse == 2) return;
if ((py->down) && (Parser__Nodes__type(py->down) == WITH_NT))
{
#line 436 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8KindQualified),
"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'.");
return;
}
#line 335 "inform7/Chapter 8/Make Assertions.w"
;
if ((py->down) && (Parser__Nodes__type(py->down) == KIND_NT))
{
#line 446 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8KindOfKindDisallowed),
"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 337 "inform7/Chapter 8/Make Assertions.w"
;
if ((py->down) && (Parser__Nodes__type(py->down) == EVERY_NT))
{
#line 455 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8KindOfEveryDisallowed),
"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 339 "inform7/Chapter 8/Make Assertions.w"
;
if (prevailing_mood != UNKNOWN_CE)
{
#line 465 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8KindUncertainDisallowed),
"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 341 "inform7/Chapter 8/Make Assertions.w"
;
inference_subject *inst = Parser__Nodes__get_subject(px);
inference_subject *kind_of_what = Parser__Nodes__get_subject(py);
if (kind_of_what == NULL) internal_error("KIND node without subject");
if ((World__Subjects__is_an_object(inst)) ||
(World__Subjects__is_a_kind_of_object(inst))) {
if ((World__Subjects__domain(inst) == FALSE) &&
(World__Subjects__where_created(inst) != current_sentence))
{
#line 366 "inform7/Chapter 8/Make Assertions.w"
Problems__quote_subject(1, inst);
Problems__quote_source(2, current_sentence);
Problems__quote_source(3, World__Subjects__where_created(inst));
Problems__handmade_problem(_P_(C8InstanceNowKind));
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 351 "inform7/Chapter 8/Make Assertions.w"
;
pcalc_prop *subject_to = NULL;
if (py->down) subject_to = Specifications__get_proposition(Parser__Nodes__get_evaluation(py->down));
Calculus__Propositions__assert_kind_of_subject(inst, kind_of_what, subject_to);
return;
}
{
#line 387 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Nodes__type(px) == PROPER_NOUN_NT) {
property *prn = Specifications__Values__get_property_name_if_any(
Parser__Nodes__get_evaluation(px));
if (prn) {
Problems__quote_source(1, current_sentence);
Problems__quote_property(2, prn);
Problems__quote_words_as_source(3, prn->word_ref1, prn->word_ref2);
Problems__handmade_problem(_P_(C8KindAsProperty));
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 360 "inform7/Chapter 8/Make Assertions.w"
;
{
#line 410 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Nodes__type(px) == PROPER_NOUN_NT) {
specification *val = Parser__Nodes__get_evaluation(px);
if (Specifications__Values__is_actual_CONSTANT(val)) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind_of(2, val);
Problems__quote_words_as_source(3, px->word_ref1, px->word_ref2);
Problems__handmade_problem(_P_(C8KindAsActualValue));
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 361 "inform7/Chapter 8/Make Assertions.w"
;
}
#line 171 "inform7/Chapter 8/Make Assertions.w"
; return;
case 9:
{
#line 475 "inform7/Chapter 8/Make Assertions.w"
internal_error("Forbidden case 9 in make assertion has occurred.");
}
#line 172 "inform7/Chapter 8/Make Assertions.w"
; return;
case 10:
{
#line 485 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Nodes__type(px) == KIND_NT)
{
#line 764 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8TooVagueForVariables),
"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 486 "inform7/Chapter 8/Make Assertions.w"
else
{
#line 773 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8HasNoVariables),
"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 488 "inform7/Chapter 8/Make Assertions.w"
;
}
#line 173 "inform7/Chapter 8/Make Assertions.w"
; return;
case 11:
{
#line 496 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Nodes__type(py) == COMMON_NOUN_NT) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, py->word_ref1, py->word_ref2);
Problems__quote_kind_of(3, Parser__Nodes__get_evaluation(py));
Problems__handmade_problem(_P_(C8PropertyObj2));
Problems__issue_problem_segment(
"In %1 you give a value of a property as '%2', but it "
"seems to be a general description of values (%3) rather than "
"nailing down exactly what the value should be.");
Problems__issue_problem_end();
} else Problems__assertion_problem(_P_(C8PeculiarProperty),
"that is a very peculiar property value",
"and ought to be something more definite and explicit.");
}
#line 174 "inform7/Chapter 8/Make Assertions.w"
; return;
case 12:
{
#line 513 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8KindOfIs),
"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 175 "inform7/Chapter 8/Make Assertions.w"
; return;
case 13:
{
#line 521 "inform7/Chapter 8/Make Assertions.w"
if (traverse == 1) return;
if (Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(Parser__Nodes__get_aph(py))) {
int pw1 = px->down->next->word_ref1, pw2 = px->down->next->word_ref2;
property *prn = Properties__Valued__obtain(pw1, pw2);
if (Parser__Nodes__type(px->down) == WITH_NT) {
Problems__assertion_problem(_P_(C8EOOwnerMutable),
"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 {
Parser__Sentences__NPs__turn_player_to_yourself(px->down);
Parser__Assertions__assert_property_value_from_property_subtree_infs(prn,
Parser__Nodes__get_subject(px->down), py);
}
} else {
Problems__assertion_problem(_P_(C8NonAdjectivalProperty),
"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 176 "inform7/Chapter 8/Make Assertions.w"
; return;
case 14:
{
#line 550 "inform7/Chapter 8/Make Assertions.w"
Parser__Assertions__make_assertion_recursive(px, py->down);
Parser__Assertions__make_assertion_recursive(py->down, py->down->next);
}
#line 177 "inform7/Chapter 8/Make Assertions.w"
; return;
case 15:
{
#line 556 "inform7/Chapter 8/Make Assertions.w"
Parser__Assertions__make_assertion_recursive(px->down, py);
Parser__Assertions__make_assertion_recursive(px->down, px->down->next);
}
#line 178 "inform7/Chapter 8/Make Assertions.w"
; return;
case 16:
{
#line 562 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8BadEvery),
"'every' (or 'always') can't be used in that way",
"and should be reserved for sentences like 'A coin is in every room'.");
}
#line 179 "inform7/Chapter 8/Make Assertions.w"
; return;
case 17:
{
#line 572 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8BadEvery2),
"'every' can't be used in that way",
"and should be reserved for sentences like 'A coin is in every room'.");
}
#line 180 "inform7/Chapter 8/Make Assertions.w"
; return;
case 18:
{
#line 590 "inform7/Chapter 8/Make Assertions.w"
if (traverse == 1) return;
if ((Parser__Nodes__type(px) == PROPER_NOUN_NT) &&
(Specifications__Values__is_CONSTANT_construction(Parser__Nodes__get_evaluation(px), CON_rulebook))) {
Code__Rulebooks__parse_properties(Code__Rulebooks__from_specification(Parser__Nodes__get_evaluation(px)),
Parser__Nodes__left_edge_of(py), Parser__Nodes__right_edge_of(py));
return;
}
if (Parser__Nodes__type(px) == PROPERTY_LIST_NT) Parser__Assertions__assert_property_list(py, px);
else Parser__Assertions__assert_property_list(px, py);
}
#line 181 "inform7/Chapter 8/Make Assertions.w"
; return;
case 19:
{
#line 606 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Nodes__get_subject(py))
Problems__assertion_problem(_P_(C8ActionEquated),
"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__assertion_problem(_P_(C8ActionEquated2),
"that means something else already",
"so it will only confuse things if we use it for a kind of action.");
}
#line 182 "inform7/Chapter 8/Make Assertions.w"
; return;
case 20:
{
#line 626 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Sentences__NPs__turn_player_to_yourself(px)) { Parser__Assertions__make_assertion_recursive(px, py); return; }
if (Parser__Sentences__NPs__turn_player_to_yourself(py)) { Parser__Assertions__make_assertion_recursive(px, py); return; }
Problems__assertion_problem(_P_(C8IntangibleRelated),
"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 183 "inform7/Chapter 8/Make Assertions.w"
; return;
case 21:
{
#line 642 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8XofYRelated),
"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 184 "inform7/Chapter 8/Make Assertions.w"
; return;
case 22:
{
#line 664 "inform7/Chapter 8/Make Assertions.w"
Parser__Nodes__coerce_adjectival_usage_to_noun(px);
if (Parser__Nodes__type(px) == PROPER_NOUN_NT) {
Parser__Assertions__make_assertion_recursive(px, py);
return;
}
if (traverse == 2) Parser__Assertions__Implications__new(px, py);
}
#line 185 "inform7/Chapter 8/Make Assertions.w"
; return;
case 23:
{
#line 674 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8DescriptionIsOther),
"this seems to say that a general description is something else",
"like saying that 'a door is 20'.");
}
#line 186 "inform7/Chapter 8/Make Assertions.w"
; return;
case 24:
{
#line 683 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8ActionAdjective),
"that is already the name of a property",
"so it will only confuse things if we use it for a kind of action.");
}
#line 187 "inform7/Chapter 8/Make Assertions.w"
; return;
case 25:
{
#line 693 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Sentences__NPs__turn_player_to_yourself(px)) {
Parser__Assertions__make_assertion_recursive(px, py); return;
}
specification *spec = Parser__Nodes__get_evaluation(px);
if ((Parser__Nodes__get_subject(px) == NULL) &&
(Specifications__Values__is_actual_CONSTANT_construction(spec, CON_property))) {
property *prn = RETRIEVE_POINTER_property(Specifications__get_structure_field(spec));
if ((prn) && (Properties__Valued__coincides_with_kind(prn))) {
kind *K = Properties__Valued__kind(prn);
Parser__Nodes__set_subject(px, Kinds__as_subject(K));
Parser__Nodes__set_evaluation(px, Specifications__Values__new_generic_CONSTANT(K));
Parser__Nodes__set_node_type(px, COMMON_NOUN_NT);
}
}
if (Parser__Nodes__get_subject(px) == NULL) {
kind *K = Specifications__get_kind(spec);
if (Specifications__Values__is_actual_CONSTANT(spec)) {
if (Config__Plugins__Call__offered_property(K, spec, py->down)) return;
if (Kinds__get_construct(K) == CON_activity)
{
#line 723 "inform7/Chapter 8/Make Assertions.w"
activity *av = Code__Activities__from_specification(spec);
if (av == NULL) internal_error("failed to extract activity structure");
if (traverse == 2) {
if (parse_nt_against_word_range(activity_name_formal_NTM, px->word_ref1, px->word_ref2, NULL, NULL))
Code__Activities__add_variable(av, py->down);
else
Problems__assertion_problem(_P_(C8BadActivityRef),
"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 712 "inform7/Chapter 8/Make Assertions.w"
;
if (Kinds__get_construct(K) == CON_rulebook)
{
#line 744 "inform7/Chapter 8/Make Assertions.w"
rulebook *rb = Code__Rulebooks__from_specification(spec);
if (rb == NULL) internal_error("failed to extract rulebook structure");
if (traverse == 2) {
if (parse_nt_against_word_range(rulebook_name_formal_NTM, px->word_ref1, px->word_ref2, NULL, NULL))
Code__Rulebooks__add_variable(rb, py->down);
else
Problems__assertion_problem(_P_(C8BadRulebookRef),
"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 713 "inform7/Chapter 8/Make Assertions.w"
;
}
{
#line 773 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8HasNoVariables),
"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 715 "inform7/Chapter 8/Make Assertions.w"
;
}
if (traverse == 1) Parser__Assertions__recursively_declare_properties(px, py->down);
}
#line 188 "inform7/Chapter 8/Make Assertions.w"
; return;
case 26:
{
#line 790 "inform7/Chapter 8/Make Assertions.w"
if (traverse == 1) return;
Parser__Sentences__NPs__turn_player_to_yourself(px->down);
if (parse_nt_against_word_range(negated_clause_NTM, py->word_ref1, py->word_ref2, NULL, NULL)) {
Problems__negative_sentence_problem(_P_(C8NonValue)); return;
}
specification *owner = Parser__Nodes__get_evaluation(px->down);
int pw1 = px->down->next->word_ref1, pw2 = px->down->next->word_ref2;
property *prn = Properties__Valued__obtain(pw1, pw2);
if (prn == P_specification)
{
#line 829 "inform7/Chapter 8/Make Assertions.w"
int w1 = py->word_ref1, w2 = py->word_ref2;
{
#line 852 "inform7/Chapter 8/Make Assertions.w"
if ((parse_nt_against_word_range(literal_NTM, w1, w2, NULL, NULL)) && (most_recent_result_p == K_text)) Text__dequote_word(w1);
else {
Problems__assertion_problem(_P_(C8SpecNotText),
"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 830 "inform7/Chapter 8/Make Assertions.w"
;
if (Specifications__Values__is_generic_CONSTANT(owner)) {
kind *K = Specifications__get_kind(owner);
if (Kinds__lt(K, K_object) == FALSE) {
Kinds__set_specification_text(K, Text__word_text(w1));
return;
}
} else if (Config__Plugins__Call__offered_specification(owner, w1, w2)) {
return;
} else if (Parser__Nodes__type(px->down) != COMMON_NOUN_NT) {
LOG("$T\n", current_sentence);
Problems__assertion_problem(_P_(C8Unspecifiable),
"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 799 "inform7/Chapter 8/Make Assertions.w"
;
Parser__Nodes__coerce_adjectival_usage_to_noun(px->down);
if ((Parser__Nodes__type(px->down) == PROPER_NOUN_NT) ||
(Parser__Nodes__type(px->down) == COMMON_NOUN_NT)) {
inference_subject *owner_infs = Parser__Nodes__get_subject(px->down);
if (owner_infs == NULL) {
if (parse_nt_against_word_range(k_kind_NTM, px->down->word_ref1, px->down->word_ref2, NULL, NULL))
owner_infs = Kinds__as_subject(most_recent_result_p);
}
if (Specifications__get_proposition(owner))
{
#line 865 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8OverspecifiedSpec),
"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 810 "inform7/Chapter 8/Make Assertions.w"
else if (owner_infs)
Parser__Assertions__assert_property_value_from_property_subtree_infs(prn, owner_infs, py);
else
{
#line 878 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8BadInferenceSubject),
"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 813 "inform7/Chapter 8/Make Assertions.w"
;
return;
}
{
#line 888 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8GeneralitySpec),
"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 817 "inform7/Chapter 8/Make Assertions.w"
;
}
#line 189 "inform7/Chapter 8/Make Assertions.w"
; return;
case 27:
{
#line 905 "inform7/Chapter 8/Make Assertions.w"
if (traverse == 1) return;
action_pattern *apx = Parser__Nodes__get_action_meaning(px);
action_pattern *apy = Parser__Nodes__get_action_meaning(py);
if ((Plugins__Actions__Patterns__is_valid(apy)) &&
(Plugins__Actions__Patterns__is_named(apy) == FALSE)) {
LOG("Actions: $A and $A\n", apx, apy);
Problems__assertion_problem(_P_(C8ActionsEquated),
"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 Plugins__Actions__Patterns__categorise_as(apx, py->word_ref1, py->word_ref2);
}
#line 190 "inform7/Chapter 8/Make Assertions.w"
; return;
case 28:
{
#line 927 "inform7/Chapter 8/Make Assertions.w"
if ((Parser__Nodes__int_annotation(px, relationship_node_type_ANNOT) == DIRECTION_RELN) &&
(Parser__Nodes__int_annotation(py, relationship_node_type_ANNOT) == DIRECTION_RELN)) {
Plugins__Map__enter_one_way_mode();
Parser__Assertions__make_assertion_recursive(px, py->down);
Parser__Assertions__make_assertion_recursive(px->down, py);
Plugins__Map__exit_one_way_mode();
return;
}
Problems__assertion_problem(_P_(C8RelationsEquated),
"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 191 "inform7/Chapter 8/Make Assertions.w"
; return;
case 29:
{
#line 946 "inform7/Chapter 8/Make Assertions.w"
Parser__Sentences__NPs__turn_player_to_yourself(px);
if (traverse == 2) Parser__Assertions__assert_property_list(px, py);
}
#line 192 "inform7/Chapter 8/Make Assertions.w"
; return;
case 30:
{
#line 955 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Nodes__get_subject(py))
Problems__assertion_problem(_P_(C8AdjectiveIsObject),
"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__assertion_problem(_P_(C8AdjectiveIsValue),
"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 193 "inform7/Chapter 8/Make Assertions.w"
; return;
case 31:
{
#line 970 "inform7/Chapter 8/Make Assertions.w"
if (traverse == 1) Parser__Assertions__Assemblies__make_generalisation(px, py);
}
#line 194 "inform7/Chapter 8/Make Assertions.w"
; return;
case 32:
{
#line 975 "inform7/Chapter 8/Make Assertions.w"
if ((Parser__Nodes__get_subject(px)) && (World__Subjects__domain(Parser__Nodes__get_subject(px)))) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, py);
Problems__handmade_problem(_P_(C8KindIsAction));
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__assertion_problem(_P_(C8ObjectIsAction),
"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 195 "inform7/Chapter 8/Make Assertions.w"
; return;
case 33:
{
#line 995 "inform7/Chapter 8/Make Assertions.w"
Problems__assertion_problem(_P_(C8EveryEquated),
"I can't do that", "Dave.");
}
#line 196 "inform7/Chapter 8/Make Assertions.w"
; return;
case 34:
{
#line 1005 "inform7/Chapter 8/Make Assertions.w"
{
#line 1048 "inform7/Chapter 8/Make Assertions.w"
if ((py->down) && (Parser__Nodes__type(py->down) == EVERY_NT)) {
if (traverse == 1) Parser__Assertions__Assemblies__make_generalisation(py, px);
return;
}
}
#line 1005 "inform7/Chapter 8/Make Assertions.w"
;
{
#line 1063 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Nodes__int_annotation(px, multiplicity_ANNOT) >= 1) {
Parser__Assertions__convert_instance_to_nounphrase(px, NULL);
Parser__Assertions__make_assertion_recursive(py, px);
return;
}
}
#line 1006 "inform7/Chapter 8/Make Assertions.w"
;
{
#line 1074 "inform7/Chapter 8/Make Assertions.w"
binary_predicate *bp = Parser__Nodes__get_relationship(py);
if ((bp) && ((Properties__Valued__Relations__bp_sets_a_property(bp)) ||
(Semantics__BPs__relates_values_not_objects(bp)))) {
if (traverse == 2) Parser__Assertions__assert_subtree_in_relationship(px, py);
return;
}
}
#line 1007 "inform7/Chapter 8/Make Assertions.w"
;
{
#line 1086 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Nodes__int_annotation(current_sentence, sentence_is_existential_ANNOT)) {
Parser__Assertions__convert_instance_to_nounphrase(px, NULL);
Parser__Assertions__make_assertion_recursive(py, px);
return;
}
}
#line 1008 "inform7/Chapter 8/Make Assertions.w"
;
if (prevailing_mood == CERTAIN_CE) {
Parser__Nodes__set_subject(px,
Kinds__as_subject(
Specifications__get_kind(
Parser__Nodes__get_evaluation(px))));
Parser__Nodes__set_node_type(px, EVERY_NT);
Parser__Assertions__make_assertion_recursive(px, py);
return;
}
if (Kinds__le(Specifications__get_kind(Parser__Nodes__get_evaluation(px)), K_object))
Problems__assertion_problem(_P_(C8KindRelated),
"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__assertion_problem(_P_(C8KOVRelated),
"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 197 "inform7/Chapter 8/Make Assertions.w"
; return;
case 35:
{
#line 1097 "inform7/Chapter 8/Make Assertions.w"
if ((px->down) && (Parser__Nodes__type(px->down) == EVERY_NT)) {
if (traverse == 1) Parser__Assertions__Assemblies__make_generalisation(px, py);
} else {
Parser__Assertions__convert_instance_to_nounphrase(py, Parser__Nodes__get_relationship(px));
Parser__Assertions__make_assertion_recursive(px, py);
}
}
#line 198 "inform7/Chapter 8/Make Assertions.w"
; return;
case 36:
{
#line 1109 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Sentences__NPs__turn_player_to_yourself(px)) {
Parser__Assertions__make_assertion_recursive(px, py); return;
}
instantiate_related_common_nouns(py);
if (traverse == 2) Parser__Assertions__assert_subtree_in_relationship(px, py);
}
#line 199 "inform7/Chapter 8/Make Assertions.w"
; return;
case 37:
{
#line 1118 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Sentences__NPs__turn_player_to_yourself(py)) { Parser__Assertions__make_assertion_recursive(px, py); return; }
instantiate_related_common_nouns(px);
if (traverse == 2) Parser__Assertions__assert_subtree_in_relationship(py, px);
}
#line 200 "inform7/Chapter 8/Make Assertions.w"
; return;
case 38:
{
#line 1136 "inform7/Chapter 8/Make Assertions.w"
{
#line 1166 "inform7/Chapter 8/Make Assertions.w"
if ((Specifications__Storage__is_generic_NONLOCAL_VARIABLE(Parser__Nodes__get_evaluation(px))) &&
(Specifications__Storage__is_generic_NONLOCAL_VARIABLE(Parser__Nodes__get_evaluation(py)))) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, px->word_ref1, px->word_ref2);
Problems__quote_words(3, py->word_ref1, py->word_ref2);
Problems__handmade_problem(_P_(C8VariablesEquated));
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 1136 "inform7/Chapter 8/Make Assertions.w"
;
{
#line 1186 "inform7/Chapter 8/Make Assertions.w"
if (Specifications__family_is(Parser__Nodes__get_evaluation(py), STORAGE_FMY)) {
Problems__assertion_problem(_P_(C8VarKOVClash),
"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 1137 "inform7/Chapter 8/Make Assertions.w"
;
inference_subject *left_object = Parser__Nodes__get_subject(px);
inference_subject *right_kind = Parser__Nodes__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__handmade_problem(_P_(C8SameKindEquated));
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__handmade_problem(_P_(C8DescriptionsEquated));
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 201 "inform7/Chapter 8/Make Assertions.w"
; return;
case 39:
{
#line 1219 "inform7/Chapter 8/Make Assertions.w"
if ((World__Subjects__is_an_object(Parser__Nodes__get_subject(px))) ||
(World__Subjects__is_a_kind_of_object(Parser__Nodes__get_subject(px)))) {
if ((Parser__Nodes__get_subject(py) != Kinds__as_subject(K_object)) &&
(World__Subjects__is_a_kind_of_object(Parser__Nodes__get_subject(py)) == FALSE))
issue_value_equation_problem(px, py);
else
{
#line 1347 "inform7/Chapter 8/Make Assertions.w"
inference_subject *left_object = Parser__Nodes__get_subject(px);
pcalc_prop *prop = Parser__Nodes__get_creation_proposition(py);
if (prop) {
if ((Calculus__Variables__number_free(prop) == 0) && (left_object)) {
LOG("Proposition is: $D\n", prop);
Problems__subject_problem_at_sentence(_P_(C8SubjectNotFree),
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_true_about(prop, left_object, prevailing_mood);
} else {
kind *K = Specifications__get_kind(Parser__Nodes__get_evaluation(py));
if (K) {
pcalc_prop *prop = Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0));
Calculus__Propositions__assert_true_about(prop, left_object, prevailing_mood);
}
}
}
#line 1224 "inform7/Chapter 8/Make Assertions.w"
;
return;
}
specification *g_spec = Parser__Nodes__get_evaluation(py);
specification *a_spec = Parser__Nodes__get_evaluation(px);
kind *g_kind = Specifications__get_kind_referred_to(g_spec);
if (Specifications__Storage__is_generic_NONLOCAL_VARIABLE(g_spec))
g_kind = Specifications__get_kind(g_spec);
kind *a_kind = Specifications__get_kind_referred_to(a_spec);
int var_set = FALSE;
if ((Specifications__Values__get_named_constant_if_any(a_spec)) ||
(Specifications__Storage__get_storage_form(a_spec) == NONLOCAL_VARIABLE_SPC)) {
var_set = TRUE;
if (Specifications__Storage__is_generic_NONLOCAL_VARIABLE(g_spec))
{
#line 1269 "inform7/Chapter 8/Make Assertions.w"
nonlocal_variable *nlv =
RETRIEVE_FROM_SPEC(Parser__Nodes__get_evaluation(px), nonlocal_variable);
specification *val = Parser__Nodes__get_evaluation(py);
kind *kind_as_declared = Data__NonlocalVariables__kind(nlv);
kind *constant_kind = Specifications__get_kind(val);
if (Kinds__le(constant_kind, kind_as_declared) == FALSE) {
LOG("$u, $u\n", kind_as_declared, constant_kind);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, nlv->word_ref1, nlv->word_ref2);
Problems__quote_spec(3, val);
Problems__quote_kind(4, kind_as_declared);
Problems__handmade_problem(_P_(C8GlobalRedeclared));
Problems__issue_problem_segment(
"The sentence %1 seems to tell me that '%2', which has already been declared "
"as %4 that varies, is instead '%3' - but that would be a contradiction.");
Problems__issue_problem_end();
} else {
if (Kinds__eq(kind_as_declared, constant_kind) == FALSE)
Data__NonlocalVariables__set_kind(nlv, constant_kind);
}
return;
}
#line 1238 "inform7/Chapter 8/Make Assertions.w"
;
}
if (((Specifications__Values__is_generic_CONSTANT(g_spec)) ||
(Specifications__Storage__is_generic_NONLOCAL_VARIABLE(g_spec)) ||
(Specifications__species_is(g_spec, DESCRIPTION_SPC)))
&& (a_kind)) {
if (Kinds__eq(a_kind, g_kind))
{
#line 1297 "inform7/Chapter 8/Make Assertions.w"
if ((var_set == FALSE) && (Kinds__eq(a_kind, K_number))) {
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C8Sarcasm1));
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__eq(a_kind, K_text))) {
TEMPORARY_STREAM;
Data__Strings__compile_literal(TEMP, px->word_ref1);
CLOSE_TEMPORARY_STREAM;
}
return;
}
#line 1246 "inform7/Chapter 8/Make Assertions.w"
;
if (Kinds__get_construct(a_kind) == CON_description)
{
#line 1333 "inform7/Chapter 8/Make Assertions.w"
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C8DescAsLiteral));
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 1248 "inform7/Chapter 8/Make Assertions.w"
;
}
if (var_set == FALSE)
{
#line 1315 "inform7/Chapter 8/Make Assertions.w"
if (Kinds__eq(a_kind, K_number)) {
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C8Sarcasm2));
Problems__issue_problem_segment("%1: That, sir, is a damnable lie.");
Problems__issue_problem_end();
return;
}
if (Kinds__eq(a_kind, K_text)) {
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C8Sarcasm3));
Problems__issue_problem_segment("%1: And I am the King of Siam.");
Problems__issue_problem_end();
return;
}
}
#line 1250 "inform7/Chapter 8/Make Assertions.w"
;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, px->word_ref1, px->word_ref2);
Problems__quote_kind_of(3, a_spec);
Problems__handmade_problem(_P_(C8ChangedKind));
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 202 "inform7/Chapter 8/Make Assertions.w"
; return;
case 40:
{
#line 1372 "inform7/Chapter 8/Make Assertions.w"
specification *spec = Parser__Nodes__get_evaluation(py);
{
#line 1387 "inform7/Chapter 8/Make Assertions.w"
if (Specifications__Values__get_named_constant_if_any(spec)) {
kind *c_kind = Data__Instances__kind(Specifications__Values__get_named_constant_if_any(spec));
kind *v_kind = Specifications__get_kind(Parser__Nodes__get_evaluation(px));
if ((v_kind == NULL) || (Kinds__eq(c_kind, v_kind))) return;
}
}
#line 1373 "inform7/Chapter 8/Make Assertions.w"
;
if (Kinds__le(Specifications__get_kind(Parser__Nodes__get_evaluation(py)), K_object))
issue_value_equation_problem(py, px);
else Problems__assertion_problem(_P_(C8CommonIsProper),
"this seems to say that a general description is something else",
"like saying that 'a door is 20'.");
}
#line 203 "inform7/Chapter 8/Make Assertions.w"
; return;
case 41:
{
#line 1407 "inform7/Chapter 8/Make Assertions.w"
{
#line 1579 "inform7/Chapter 8/Make Assertions.w"
if (Specifications__Values__is_actual_CONSTANT_construction(Parser__Nodes__get_evaluation(px), CON_property)) {
inference_subject *talking_about = Parser__Assertions__get_current_subject();
if (talking_about == NULL)
Problems__assertion_problem(_P_(C8NothingDiscussed),
"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 (parse_nt_against_word_range(negated_clause_NTM, py->word_ref1, py->word_ref2, NULL, NULL))
Problems__negative_sentence_problem(_P_(C8NonValue2));
else Parser__Assertions__assert_property_value_from_property_subtree_infs(
Properties__from_specification(Parser__Nodes__get_evaluation(px)), talking_about, py);
}
return;
}
}
#line 1407 "inform7/Chapter 8/Make Assertions.w"
;
{
#line 1606 "inform7/Chapter 8/Make Assertions.w"
specification *constant = Parser__Nodes__get_evaluation(px);
if ((Specifications__Values__get_named_constant_if_any(constant)) ||
(Specifications__Values__is_generic_CONSTANT(constant))) {
instance *q = Specifications__Values__get_named_constant_if_any(Parser__Nodes__get_evaluation(py));
property *pname = Kinds__get_coinciding_property(Data__Instances__kind(q));
if (pname) {
if (traverse == 2)
Parser__Assertions__assert_property_value_from_property_subtree_infs(pname, Data__Instances__as_subject(q), py);
return;
}
}
}
#line 1408 "inform7/Chapter 8/Make Assertions.w"
;
{
#line 1621 "inform7/Chapter 8/Make Assertions.w"
specification *constant = Parser__Nodes__get_evaluation(px);
specification *val = Parser__Nodes__get_evaluation(py);
if ((Specifications__Values__is_actual_CONSTANT_of_kind(constant, K_response)) &&
(Specifications__Values__is_actual_CONSTANT_of_kind(val, K_text))) {
rule *R = Code__Rules__from_specification(constant);
int c = Specifications__get_data(constant, RESPONSE_CODE_SPDATA);
Data__Strings__assert_response_value(R, c, val->word_ref1);
return;
}
}
#line 1409 "inform7/Chapter 8/Make Assertions.w"
;
{
#line 1559 "inform7/Chapter 8/Make Assertions.w"
if (Specifications__Storage__get_storage_form(Parser__Nodes__get_evaluation(px)) == NONLOCAL_VARIABLE_SPC) {
nonlocal_variable *nlv = RETRIEVE_FROM_SPEC(Parser__Nodes__get_evaluation(px), nonlocal_variable);
if (nlv) {
specification *val = Parser__Nodes__get_evaluation(py);
if (val) { val->word_ref1 = py->word_ref1; val->word_ref2 = py->word_ref2; }
val = Data__NonlocalVariables__substitute_constants(val);
if (traverse == 2) {
Parser__Assertions__initialise_global_variable(nlv, val);
} else {
if (Specifications__Values__is_actual_CONSTANT(val))
if (Config__Plugins__Call__variable_set_warning(nlv, val))
Parser__Assertions__initialise_global_variable(nlv, val);
}
return;
}
}
}
#line 1410 "inform7/Chapter 8/Make Assertions.w"
;
{
#line 1641 "inform7/Chapter 8/Make Assertions.w"
if (Specifications__Values__is_actual_CONSTANT_construction(Parser__Nodes__get_evaluation(py), CON_property)) {
property *prn = Properties__from_specification(Parser__Nodes__get_evaluation(py));
if ((Properties__is_either_or(prn) == FALSE) &&
(Properties__Valued__coincides_with_kind(prn))) {
kind *K = Properties__Valued__kind(prn);
Parser__Nodes__set_evaluation(py, Specifications__Values__new_generic_CONSTANT(K));
Parser__Nodes__set_node_type(py, COMMON_NOUN_NT);
Parser__Assertions__make_assertion_recursive(px, py);
return;
}
}
}
#line 1411 "inform7/Chapter 8/Make Assertions.w"
;
kind *K = Specifications__get_kind(Parser__Nodes__get_evaluation(py));
property *pname = Kinds__get_coinciding_property(K);
if (pname) {
if (traverse == 2)
Parser__Assertions__assert_property_value_from_property_subtree_infs(pname, Parser__Nodes__get_subject(px), py);
return;
}
if ((Plugins__Map__is_a_direction(Parser__Nodes__get_subject(px))) ||
(Plugins__Map__is_a_direction(Parser__Nodes__get_subject(py))))
{
#line 1441 "inform7/Chapter 8/Make Assertions.w"
if (Parser__Assertions__get_current_subject() == NULL) {
Problems__assertion_problem(_P_(C8NoMapOrigin),
"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 = Parser__Nodes__get_subject(py), *way = Parser__Nodes__get_subject(px);
if (Plugins__Map__is_a_direction(target)) {
target = Parser__Nodes__get_subject(px); way = Parser__Nodes__get_subject(py);
}
if (traverse == 2) Plugins__Map__connect(Parser__Assertions__get_current_subject(), target, way);
}
#line 1423 "inform7/Chapter 8/Make Assertions.w"
else if (Specifications__Values__is_actual_CONSTANT_object(Parser__Nodes__get_evaluation(py)))
{
#line 1456 "inform7/Chapter 8/Make Assertions.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, px->word_ref1, px->word_ref2);
Problems__quote_words(3, py->word_ref1, py->word_ref2);
if (Parser__Nodes__get_subject(px) == Parser__Nodes__get_subject(py))
Problems__assertion_problem(_P_(C8ProperIsItself),
"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 (parse_nt_against_word_range(control_structure_phrase_NTM, px->word_ref1, px->word_ref2, NULL, NULL)) {
Problems__handmade_problem(_P_(C8IfInAssertion));
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 (Specifications__Values__is_actual_CONSTANT_object(
Parser__Nodes__get_evaluation(px)))
{
#line 1499 "inform7/Chapter 8/Make Assertions.w"
{
#line 1518 "inform7/Chapter 8/Make Assertions.w"
char *P, *Q, *In;
int variant = 0;
if (!fix_rng_at_start_of_play) 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 1499 "inform7/Chapter 8/Make Assertions.w"
;
Problems__handmade_problem(_P_(C8ChalkCheese));
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__diagnose_further();
Problems__issue_problem_end();
}
#line 1479 "inform7/Chapter 8/Make Assertions.w"
else
{
#line 1485 "inform7/Chapter 8/Make Assertions.w"
Problems__quote_kind_of(4, Parser__Nodes__get_evaluation(px));
Problems__quote_kind_of(5, Parser__Nodes__get_evaluation(py));
Problems__handmade_problem(_P_(C8ObjectAndValueEquated));
Problems__issue_problem_segment(
"This 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 1480 "inform7/Chapter 8/Make Assertions.w"
;
}
#line 1425 "inform7/Chapter 8/Make Assertions.w"
else if (Specifications__Values__is_actual_CONSTANT_construction(Parser__Nodes__get_evaluation(py), CON_property))
Problems__assertion_problem(_P_(C8ObjectIsProperty),
"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 (Parser__Nodes__get_subject(px))
Problems__assertion_problem(_P_(C8ObjectIsValue),
"this seems to say that a thing is a value",
"like saying 'the chair is 10'.");
else
{
#line 1656 "inform7/Chapter 8/Make Assertions.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, px->word_ref1, px->word_ref2);
Problems__quote_words(3, py->word_ref1, py->word_ref2);
Problems__quote_kind_of(4, Parser__Nodes__get_evaluation(px));
Problems__quote_kind_of(5, Parser__Nodes__get_evaluation(py));
if (Kinds__eq(Specifications__get_kind(Parser__Nodes__get_evaluation(px)),
Specifications__get_kind(Parser__Nodes__get_evaluation(py)))) {
Problems__handmade_problem(_P_(C8SimilarValuesEquated));
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__handmade_problem(_P_(C8DissimilarValuesEquated));
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 1436 "inform7/Chapter 8/Make Assertions.w"
;
}
#line 204 "inform7/Chapter 8/Make Assertions.w"
; return;
case 42:
{
#line 1712 "inform7/Chapter 8/Make Assertions.w"
if ((convert_adjective_to_noun(px)) || (convert_adjective_to_noun(py->down))) {
Parser__Assertions__make_assertion_recursive(px, py);
return;
}
Problems__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 205 "inform7/Chapter 8/Make Assertions.w"
; return;
default: LOG("Unimplemented assertion case %d\n", ma_case);
internal_error("No implementation for make assertion case");
}
}
#line 108 "inform7/Chapter 8/Make Assertions.w"
;
}
#line 1689 "inform7/Chapter 8/Make Assertions.w"
int something_loose_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 1695 "inform7/Chapter 8/Make Assertions.w"
Problems__sentence_problem(_P_(C8EquatesSomethingToValue),
"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 1690 "inform7/Chapter 8/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 1691 "inform7/Chapter 8/Make Assertions.w"
#line 1725 "inform7/Chapter 8/Make Assertions.w"
int convert_adjective_to_noun(parse_node *p) {
if ((Parser__Nodes__type(p) == ADJECTIVE_NT) &&
(Parser__Nodes__int_annotation(p, negated_boolean_ANNOT) == FALSE)) {
if (parse_nt_against_word_range(spec_value_NTM, p->word_ref1, p->word_ref2, NULL, NULL))
Parser__Nodes__noun_from_value(p, most_recent_result_p);
if (Parser__Nodes__type(p) != ADJECTIVE_NT) return TRUE;
}
return FALSE;
}
#line 1738 "inform7/Chapter 8/Make Assertions.w"
void issue_value_equation_problem(parse_node *px, parse_node *py) {
if ((current_sentence) &&
(parse_nt_against_word_range(something_loose_diagnosis_NTM, current_sentence->word_ref1, current_sentence->word_ref2, NULL, NULL)))
return;
if ((Parser__Nodes__type(px) != PROPER_NOUN_NT) ||
((Parser__Nodes__type(py) != PROPER_NOUN_NT) && (Parser__Nodes__type(py) != COMMON_NOUN_NT))) {
Parser__Nodes__log_subtree(px, 1); Parser__Nodes__log_subtree(py, 1);
internal_error("Assert PX of type PY on bad node types");
}
Parser__Nodes__log_subtree(px,1); Parser__Nodes__log_subtree(py,1);
if ((Parser__Nodes__get_subject(px)) &&
(World__Subjects__where_created(Parser__Nodes__get_subject(px)) != current_sentence)) {
Problems__quote_words(1, px->word_ref1, px->word_ref2);
Problems__quote_source(2, current_sentence);
Problems__quote_source(3, World__Subjects__where_created(Parser__Nodes__get_subject(px)));
Problems__handmade_problem(_P_(C8CantUncreate));
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 ((Parser__Nodes__type(px) == PROPER_NOUN_NT) && (Parser__Nodes__type(py) == COMMON_NOUN_NT)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, py->word_ref1, py->word_ref2);
if (px->word_ref1 >= 0) Problems__quote_words(3, px->word_ref1, px->word_ref2);
else Problems__quote_text(3, "(something not given an explicit name)");
Problems__handmade_problem(_P_(C8IdentityUnclear));
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__sentence_problem(_P_(BelievedImpossible),
"that seems to say that an object is the same as a value",
"which must be wrong.");
}
#line 1793 "inform7/Chapter 8/Make Assertions.w"
void instantiate_related_common_nouns(parse_node *p) {
instantiate_related_common_nouns_r(p, p->down);
}
void instantiate_related_common_nouns_r(parse_node *from, parse_node *at) {
if (at == NULL) return;
if (Parser__Nodes__type(at) == COMMON_NOUN_NT)
Parser__Assertions__convert_instance_to_nounphrase(at,
Parser__Nodes__get_relationship(from));
if (Parser__Nodes__type(at) == AND_NT) {
instantiate_related_common_nouns_r(from, at->down);
instantiate_related_common_nouns_r(from, at->down->next);
}
if (Parser__Nodes__type(at) == WITH_NT)
instantiate_related_common_nouns_r(from, at->down);
}
#line 13 "inform7/Chapter 8/Property Knowledge.w"
void Parser__Assertions__initialise_global_variable(nonlocal_variable *q, specification *val) {
igv_dash(q, val, FALSE);
}
void Parser__Assertions__verify_global_variable(nonlocal_variable *q) {
specification *init = Data__NonlocalVariables__get_initial_value(q);
if (init) igv_dash(q, init, TRUE);
}
#line 25 "inform7/Chapter 8/Property Knowledge.w"
void igv_dash(nonlocal_variable *q, specification *val, int verification_stage) {
if (q == NULL) internal_error("tried to initialise null variable");
kind *kind_as_declared = Data__NonlocalVariables__kind(q);
kind *constant_kind = Specifications__evaluates_to(val);
int outcome = Kinds__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 8/Property Knowledge.w"
LOG("Variable: $u; constant: $u\n", kind_as_declared, constant_kind);
specification *dummy1 = Specifications__Values__new_generic_CONSTANT(kind_as_declared),
*dummy2 = Specifications__Values__new_generic_CONSTANT(constant_kind);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, q->word_ref1, q->word_ref2);
Problems__quote_spec(3, val);
Problems__quote_spec(4, dummy1);
Problems__quote_spec(5, dummy2);
if ((Kinds__lt(kind_as_declared, K_object)) &&
(Specifications__Values__is_nothing_object_constant(val))) {
Problems__handmade_problem(_P_(C8QuantityKindNothing));
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__handmade_problem(_P_(C8GlobalKindWrong));
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.");
Problems__diagnose_further();
Problems__issue_problem_end();
}
return;
}
#line 36 "inform7/Chapter 8/Property Knowledge.w"
;
if (verification_stage) return;
specification *var = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(q);
pcalc_prop *prop = Calculus__Propositions__to_set_relation(R_equality, NULL, var, NULL, val);
Calculus__Propositions__assert_true(prop, prevailing_mood);
}
#line 100 "inform7/Chapter 8/Property Knowledge.w"
void Parser__Assertions__assert_property_value_from_property_subtree_infs(property *prn,
inference_subject *owner, parse_node *val_subtree) {
pcalc_prop *prop = Calculus__Propositions__from_property_subtree(prn, val_subtree);
Calculus__Propositions__assert_true_about(prop, owner, prevailing_mood);
}
void Parser__Assertions__assert_property_list(parse_node *owner_subtree, parse_node *list_subtree) {
{
#line 147 "inform7/Chapter 8/Property Knowledge.w"
specification *owner_spec = Parser__Nodes__get_evaluation(owner_subtree);
if (Specifications__species_is(owner_spec, DESCRIPTION_SPC)) {
if ((Calculus__Propositions__contains_binary_predicate(Specifications__get_proposition(owner_spec))) ||
(Specifications__Conditions__number_of_adjectives_applied_to(owner_spec) > 0) ||
(Calculus__Propositions__contains_adjective(Specifications__get_proposition(owner_spec)))) {
Problems__quote_source(1, current_sentence);
Problems__quote_spec(2, owner_spec);
Problems__handmade_problem(_P_(C8RelationAPL));
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 107 "inform7/Chapter 8/Property Knowledge.w"
;
inference_subject *owner = Parser__Nodes__get_subject(owner_subtree);
if (owner == NULL) {
specification *owner_spec = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, owner_subtree->word_ref1, owner_subtree->word_ref2, NULL, NULL))
owner_spec = most_recent_result_p;
if (Specifications__species_is(owner_spec, DESCRIPTION_SPC)) {
kind *K = Specifications__Conditions__get_described_kind(owner_spec);
if (Kinds__lt(K, K_object)) owner = Kinds__as_subject(K);
}
if (Specifications__Values__is_generic_CONSTANT(owner_spec))
owner = Kinds__as_subject(Specifications__evaluates_to(owner_spec));
}
if (owner == NULL)
{
#line 168 "inform7/Chapter 8/Property Knowledge.w"
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C8PropForBadKOV));
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 120 "inform7/Chapter 8/Property Knowledge.w"
;
kind *kind_clue = NULL;
{
#line 136 "inform7/Chapter 8/Property Knowledge.w"
if (owner) {
kind_clue = World__Subjects__domain(owner);
if (kind_clue == NULL) kind_clue = World__Subjects__domain(World__Subjects__narrowest_broader_subject(owner));
if ((World__Subjects__is_an_object(owner)) ||
(World__Subjects__is_a_kind_of_object(owner)))
kind_clue = K_object;
}
}
#line 122 "inform7/Chapter 8/Property Knowledge.w"
;
pcalc_prop *prop = Calculus__Propositions__from_property_list(list_subtree, kind_clue);
Calculus__Propositions__assert_true_about(prop, owner, prevailing_mood);
}
#line 186 "inform7/Chapter 8/Property Knowledge.w"
specification *Parser__Assertions__property_value_from_property_subtree(property *prn, parse_node *py) {
if (Properties__is_either_or(prn)) {
if (py == NULL)
{
#line 206 "inform7/Chapter 8/Property Knowledge.w"
Problems__quote_source(1, current_sentence);
Problems__quote_property(3, prn);
Problems__handmade_problem(_P_(C8HasBareAdjective));
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 188 "inform7/Chapter 8/Property Knowledge.w"
;
{
#line 220 "inform7/Chapter 8/Property Knowledge.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, py->word_ref1, py->word_ref2);
Problems__quote_property(3, prn);
Problems__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 189 "inform7/Chapter 8/Property Knowledge.w"
;
}
{
#line 233 "inform7/Chapter 8/Property Knowledge.w"
Parser__Nodes__coerce_adjectival_usage_to_noun(py);
switch(Parser__Nodes__type(py)) {
case PROPER_NOUN_NT: break; /* (this is fine -- there's a well-expressed value) */
case COMMON_NOUN_NT:
Problems__sentence_problem(_P_(C8PropertyInstance),
"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__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:
Problems__sentence_problem(_P_(C8MisplacedFrom),
"something grammatically odd has happened here",
"possibly to do with the unexpected 'from' in what seems to be a list of "
"property values? Maybe there is some punctuation missing.");
return NULL;
default: internal_error_on_node_type(py);
}
}
#line 191 "inform7/Chapter 8/Property Knowledge.w"
;
specification *val = Data__NonlocalVariables__substitute_constants(
Parser__Nodes__get_evaluation(py));
kind *property_kind = Properties__Valued__kind(prn);
if ((Specifications__is_evaluating(val)) && (Specifications__species_is(val, CONSTANT_SPC) == FALSE))
{
#line 264 "inform7/Chapter 8/Property Knowledge.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, py->word_ref1, py->word_ref2);
Problems__quote_kind_of(3, Specifications__Values__new_generic_CONSTANT(property_kind));
Problems__quote_property(4, prn);
Problems__handmade_problem(_P_(C8PropertyNonConstant));
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 198 "inform7/Chapter 8/Property Knowledge.w"
;
return val;
}
#line 16 "inform7/Chapter 8/Relation Knowledge.w"
void Parser__Assertions__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 (Parser__Nodes__type(relationship_subtree) != RELATIONSHIP_NT)
internal_error("asserted malformed relationship subtree");
if (Parser__Nodes__type(value) == AND_NT) {
Parser__Assertions__assert_subtree_in_relationship(value->down, relationship_subtree);
Parser__Assertions__assert_subtree_in_relationship(value->down->next, relationship_subtree);
return;
}
switch(Parser__Nodes__int_annotation(relationship_subtree, relationship_node_type_ANNOT)) {
case STANDARD_RELN:
{
#line 38 "inform7/Chapter 8/Relation Knowledge.w"
binary_predicate *bp = Semantics__BPs__get_reversal(Parser__Nodes__get_relationship(relationship_subtree));
if (bp == NULL) internal_error("asserted bp-less relationship subtree");
Properties__Valued__Relations__fix_property_bp(bp);
assert_relation_between_subtrees(value, bp, relationship_subtree->down);
break;
}
#line 28 "inform7/Chapter 8/Relation Knowledge.w"
;
case PARENTAGE_HERE_RELN:
{
#line 47 "inform7/Chapter 8/Relation Knowledge.w"
if (Parser__Nodes__get_subject(value) == NULL) {
Problems__sentence_problem(_P_(C8HereFailedOnNothing),
"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_true_about(
Calculus__Propositions__to_put_here(),
Parser__Nodes__get_subject(value), prevailing_mood);
}
break;
}
#line 29 "inform7/Chapter 8/Relation Knowledge.w"
;
case DIRECTION_RELN:
{
#line 63 "inform7/Chapter 8/Relation Knowledge.w"
{
#line 81 "inform7/Chapter 8/Relation Knowledge.w"
if ((relationship_subtree->down == NULL) ||
(relationship_subtree->down->next == NULL) ||
(relationship_subtree->down->next->next != NULL))
internal_error("malformed DIRECTION");
if (Parser__Nodes__type(relationship_subtree->down) != PROPER_NOUN_NT) {
Problems__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 (Parser__Nodes__type(relationship_subtree->down->next) != PROPER_NOUN_NT) {
Problems__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 8/Relation Knowledge.w"
;
inference_subject *iy = Parser__Nodes__get_subject(relationship_subtree->down);
inference_subject *id = Parser__Nodes__get_subject(relationship_subtree->down->next);
if (iy == NULL) {
Problems__sentence_problem(_P_(C8MapFromNowhere),
"the source of a map connection can't be nowhere",
"so sentences like 'The pink door is south of nowhere.' are not "
"allowed.");
break;
}
if ((iy == NULL) || (id == NULL))
internal_error("malformed directional subtree");
Plugins__Map__connect(iy, Parser__Nodes__get_subject(value), id);
break;
}
#line 30 "inform7/Chapter 8/Relation Knowledge.w"
;
default: internal_error("unknown RELATIONSHIP node type");
}
}
#line 103 "inform7/Chapter 8/Relation Knowledge.w"
void assert_relation_between_subtrees(parse_node *px, binary_predicate *bp, parse_node *py) {
if (Parser__Nodes__type(py) == AND_NT) {
assert_relation_between_subtrees(px, bp, py->down);
assert_relation_between_subtrees(px, bp, py->down->next);
return;
}
if (Parser__Nodes__type(py) == WITH_NT) {
assert_relation_between_subtrees(px, bp, py->down);
return;
}
if (Parser__Nodes__type(py) == EVERY_NT)
{
#line 161 "inform7/Chapter 8/Relation Knowledge.w"
Problems__sentence_problem(_P_(C8EveryWrongSide),
"'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 113 "inform7/Chapter 8/Relation Knowledge.w"
;
/* reverse the relation (and swap the terms) to ensure it's the right way round */
if (Semantics__BPs__is_the_wrong_way_round(bp)) {
parse_node *pz = px; px = py; py = pz;
bp = Semantics__BPs__get_reversal(bp);
}
{
#line 132 "inform7/Chapter 8/Relation Knowledge.w"
Parser__Nodes__coerce_adjectival_usage_to_noun(px); Parser__Sentences__NPs__turn_player_to_yourself(px);
Parser__Nodes__coerce_adjectival_usage_to_noun(py); Parser__Sentences__NPs__turn_player_to_yourself(py);
if (((Parser__Nodes__type(px) != PROPER_NOUN_NT) && (Parser__Nodes__type(px) != COMMON_NOUN_NT)) ||
((Parser__Nodes__type(py) != PROPER_NOUN_NT) && (Parser__Nodes__type(py) != COMMON_NOUN_NT))) {
Problems__sentence_problem(_P_(C8BadRelation),
"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 121 "inform7/Chapter 8/Relation Knowledge.w"
;
{
#line 147 "inform7/Chapter 8/Relation Knowledge.w"
if ((Semantics__BPs__relates_values_not_objects(bp)) &&
(((Parser__Nodes__get_subject(px)) && (World__Subjects__domain(Parser__Nodes__get_subject(px)))) ||
((Parser__Nodes__get_subject(py)) && (World__Subjects__domain(Parser__Nodes__get_subject(py)))))) {
Problems__sentence_problem(_P_(C8KindRelatedToValue),
"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.)");
return;
}
}
#line 122 "inform7/Chapter 8/Relation Knowledge.w"
;
Calculus__Propositions__assert_true(
Calculus__Propositions__to_set_relation(bp, Parser__Nodes__get_subject(px), Parser__Nodes__get_evaluation(px), Parser__Nodes__get_subject(py), Parser__Nodes__get_evaluation(py)),
prevailing_mood);
}
#line 76 "inform7/Chapter 8/Assemblies.w"
void Parser__Assertions__Assemblies__initialise_assemblies_data(assemblies_data *ad) {
ad->generalisation_list = NULL;
ad->applications_so_far = NULL;
ad->named_after = NULL;
ad->named_after_w1 = -1; ad->named_after_w2 = -1;
}
#line 86 "inform7/Chapter 8/Assemblies.w"
void Parser__Assertions__Assemblies__name_object_after(inference_subject *infs, inference_subject *after, int w1, int w2) {
assemblies_data *ad = World__Subjects__get_assemblies_data(infs);
ad->named_after = after;
ad->named_after_w1 = w1; ad->named_after_w2 = w2;
}
#line 95 "inform7/Chapter 8/Assemblies.w"
inference_subject *Parser__Assertions__Assemblies__what_this_is_named_after(inference_subject *infs) {
assemblies_data *ad = World__Subjects__get_assemblies_data(infs);
return ad->named_after;
}
void Parser__Assertions__Assemblies__get_named_after_text(inference_subject *infs, int *n1, int *n2) {
assemblies_data *ad = World__Subjects__get_assemblies_data(infs);
*n1 = ad->named_after_w1; *n2 = ad->named_after_w2;
}
#line 119 "inform7/Chapter 8/Assemblies.w"
void Parser__Assertions__Assemblies__make_generalisation(parse_node *look_for, parse_node *what_to_make) {
parse_node *EVERY_node = NULL;
if (Parser__Nodes__type(look_for) == EVERY_NT) EVERY_node = look_for;
else if ((look_for->down) && (Parser__Nodes__type(look_for->down) == EVERY_NT))
EVERY_node = look_for->down;
else internal_error("Generalisation without EVERY node");
inference_subject *k = Parser__Nodes__get_subject(EVERY_node);
if (k == NULL) internal_error("Malformed EVERY node");
if ((subtree_mentions_kind(look_for,k,0)) || (subtree_mentions_kind(what_to_make,k,0)))
{
#line 191 "inform7/Chapter 8/Assemblies.w"
LOG("Generalisation:\n");
Parser__Nodes__log_subtree(look_for, 1);
Parser__Nodes__log_subtree(what_to_make, 1);
Problems__sentence_problem(_P_(C8AssemblyRegress),
"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 8/Assemblies.w"
;
{
#line 154 "inform7/Chapter 8/Assemblies.w"
kind *instance_kind = World__Subjects__as_nonobject_kind(k);
if ((instance_kind) &&
(Kinds__le(instance_kind, K_object) == FALSE) &&
(Kinds__has_named_constant_values(instance_kind) == FALSE)) {
Parser__Nodes__log_subtree(look_for, 1);
Parser__Nodes__log_subtree(what_to_make, 1);
Problems__sentence_problem(_P_(C8AssemblyOnFixedKind),
"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 8/Assemblies.w"
;
{
#line 171 "inform7/Chapter 8/Assemblies.w"
specification *val = Parser__Nodes__get_evaluation(what_to_make);
if ((val) && (Specifications__Conditions__is_adjectives_plus_kind_of_object_DESCRIPTION(val)))
Parser__Nodes__refine_from_docket(what_to_make, Specifications__copy(val));
}
#line 132 "inform7/Chapter 8/Assemblies.w"
;
EVERY_node->word_ref1 = -1;
EVERY_node->word_ref2 = -1;
generalisation *g = CREATE(generalisation);
g->look_for = look_for;
g->what_to_make = what_to_make;
g->substitute_at = EVERY_node;
g->copied = *what_to_make;
{
#line 178 "inform7/Chapter 8/Assemblies.w"
assemblies_data *ad = World__Subjects__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 143 "inform7/Chapter 8/Assemblies.w"
;
LOGIF(ASSEMBLIES, "New generalisation made concerning $j:\nLook for: $T\nMake: $T\n",
k, g->look_for, g->what_to_make);
ensure_all_generalisations_made(k);
}
#line 204 "inform7/Chapter 8/Assemblies.w"
int subtree_mentions_kind(parse_node *subtree, inference_subject *k, int level) {
if ((Parser__Nodes__type(subtree) == COMMON_NOUN_NT) &&
(Parser__Nodes__get_subject(subtree) == k)) return TRUE;
if ((subtree->down) && (subtree_mentions_kind(subtree->down, k, level+1)))
return TRUE;
if ((level>0) && (subtree->next) && (subtree_mentions_kind(subtree->next, k, level)))
return TRUE;
return FALSE;
}
#line 220 "inform7/Chapter 8/Assemblies.w"
void ensure_all_generalisations_made(inference_subject *k) {
inference_subject *infs;
LOOP_OVER(infs, inference_subject)
if ((World__Subjects__is_within(infs, k)) && (World__Subjects__domain(infs) == NULL))
Parser__Assertions__Assemblies__satisfies_generalisations(infs);
}
#line 234 "inform7/Chapter 8/Assemblies.w"
void Parser__Assertions__Assemblies__satisfies_generalisations(inference_subject *infs) {
if (World__Subjects__domain(infs)) return;
inference_subject *k;
for (k = World__Subjects__narrowest_broader_subject(infs); k; k = World__Subjects__narrowest_broader_subject(k)) {
application *app;
for (app = World__Subjects__get_assemblies_data(infs)->applications_so_far; app; app = app->next)
if (app->generalisation_owner == k)
break;
{
#line 251 "inform7/Chapter 8/Assemblies.w"
generalisation *ignore_up_to = (app)?(app->latest_applied):NULL;
generalisation *g;
for (g = World__Subjects__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 266 "inform7/Chapter 8/Assemblies.w"
app = CREATE(application);
app->generalisation_owner = k;
app->next = World__Subjects__get_assemblies_data(infs)->applications_so_far;
World__Subjects__get_assemblies_data(infs)->applications_so_far = app;
}
#line 258 "inform7/Chapter 8/Assemblies.w"
;
app->latest_applied = g;
satisfies_generalisation(infs, g);
}
}
#line 242 "inform7/Chapter 8/Assemblies.w"
;
}
}
#line 301 "inform7/Chapter 8/Assemblies.w"
int implicit_recursion_exception = FALSE; /* thrown when we've gone into infinite regress */
void satisfies_generalisation(inference_subject *infs, generalisation *g) {
inference_subject *counterpart = NULL; int snatcher = FALSE;
if (Config__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 = Parser__Nodes__get_subject(g->substitute_at);
{
#line 357 "inform7/Chapter 8/Assemblies.w"
if (Parser__Nodes__int_annotation(current_sentence, implicitness_count_ANNOT) >= MAX_ASSEMBLY_SIZE) {
if (implicit_recursion_exception) return;
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__handmade_problem(_P_(C8AssemblyLoop));
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 310 "inform7/Chapter 8/Assemblies.w"
;
parse_node *new_sentence = Parser__Nodes__new(SENTENCE_NT);
/* mark this sentence as implicit, and increase its generation count: */
Parser__Nodes__set_implicit_in_creation_of(new_sentence, infs);
Parser__Nodes__annotate_int(new_sentence, implicitness_count_ANNOT,
Parser__Nodes__int_annotation(current_sentence, implicitness_count_ANNOT) + 1);
new_sentence->word_ref1 = current_sentence->word_ref1;
new_sentence->word_ref2 = current_sentence->word_ref2;
/* temporarily make the |EVERY_NT| node refer to the specific new |infs|: */
Parser__Nodes__noun_from_infs(g->substitute_at, infs);
/* make the new sentence an assertion: */
new_sentence->down = Parser__Nodes__new(VERB_NT);
Parser__Nodes__annotate_int(new_sentence->down, verb_id_ANNOT, ASSERT_VB);
new_sentence->down->next = Parser__Nodes__new(CREATED_NT);
Parser__Nodes__deep_copy_tree(g->look_for, new_sentence->down->next, 0);
new_sentence->down->next->next = Parser__Nodes__new(CREATED_NT);
Parser__Nodes__deep_copy_tree(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: */
Parser__Nodes__set_node_type(g->substitute_at, EVERY_NT);
Parser__Nodes__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 45 "inform7/Chapter 8/Implications.w"
void Parser__Assertions__Implications__new(parse_node *px, parse_node *py) {
if (prevailing_mood == CERTAIN_CE)
{
#line 58 "inform7/Chapter 8/Implications.w"
Problems__sentence_problem(_P_(C8ImplicationCertain),
"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 46 "inform7/Chapter 8/Implications.w"
;
if (Parser__Nodes__type(py) == AND_NT) {
Parser__Assertions__Implications__new(px, py->down);
Parser__Assertions__Implications__new(px, py->down->next);
return;
}
{
#line 70 "inform7/Chapter 8/Implications.w"
inference_subject *premiss_kind = NULL;
pcalc_prop *premiss = NULL;
{
#line 90 "inform7/Chapter 8/Implications.w"
parse_node *loc = px;
if (Parser__Nodes__type(loc) == WITH_NT) loc = loc->down;
premiss_kind = Parser__Nodes__get_subject(loc);
premiss = Parser__Nodes__get_creation_proposition(loc);
if (premiss_kind == NULL) premiss_kind = Kinds__as_subject(K_thing);
}
#line 72 "inform7/Chapter 8/Implications.w"
;
{
#line 99 "inform7/Chapter 8/Implications.w"
if (Calculus__Propositions__testable_at_compile_time(premiss) == FALSE) {
Problems__sentence_problem(_P_(C8BadImplicationDomain),
"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 73 "inform7/Chapter 8/Implications.w"
;
{
#line 112 "inform7/Chapter 8/Implications.w"
property *prn = Semantics__Adjectives__Phrases__has_EORP_meaning(Parser__Nodes__get_aph(py));
if (prn == NULL) {
Problems__sentence_problem(_P_(C8ImplicationValueProperty),
"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 74 "inform7/Chapter 8/Implications.w"
;
implication *imp = CREATE(implication);
imp->if_spec = premiss;
imp->then_pn = py;
imp->implied_likelihood = prevailing_mood;
imp->next_implication = World__Subjects__get_implications(premiss_kind);
World__Subjects__set_implications(premiss_kind, imp);
LOGIF(IMPLICATIONS, "Forming implication for $j: $D implies\n $T",
premiss_kind, imp->if_spec, imp->then_pn);
}
#line 52 "inform7/Chapter 8/Implications.w"
;
}
#line 140 "inform7/Chapter 8/Implications.w"
void Parser__Assertions__Implications__consider_all(inference_subject *infs) {
if (World__Subjects__domain(infs)) return;
int ongoing = TRUE;
while (ongoing) {
{
#line 156 "inform7/Chapter 8/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 144 "inform7/Chapter 8/Implications.w"
;
set_possessed_flags(infs);
ongoing = check_implications_of(infs, infs);
}
}
#line 167 "inform7/Chapter 8/Implications.w"
void set_possessed_flags(inference_subject *infs) {
inference_subject *k = World__Subjects__narrowest_broader_subject(infs);
if (k) 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 184 "inform7/Chapter 8/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 200 "inform7/Chapter 8/Implications.w"
if (pom->possession_certainty < certainty) {
pom->possessed = truth_state;
pom->possession_certainty = certainty;
}
}
#line 188 "inform7/Chapter 8/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 200 "inform7/Chapter 8/Implications.w"
if (pom->possession_certainty < certainty) {
pom->possessed = truth_state;
pom->possession_certainty = certainty;
}
}
#line 194 "inform7/Chapter 8/Implications.w"
;
}
}
#line 175 "inform7/Chapter 8/Implications.w"
;
}
}
#line 215 "inform7/Chapter 8/Implications.w"
int check_implications_of(inference_subject *domain, inference_subject *candidate) {
inference_subject *k = World__Subjects__narrowest_broader_subject(domain);
if ((k) && (check_implications_of(k, candidate))) return TRUE;
if (World__Subjects__get_implications(domain))
LOGIF(IMPLICATIONS, "Considering implications about $j as they apply to $j:\n",
domain, candidate);
implication *imp;
for (imp = World__Subjects__get_implications(domain); imp; imp = imp->next_implication)
{
#line 233 "inform7/Chapter 8/Implications.w"
int conclusion_state = TRUE;
if (Parser__Nodes__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 = Semantics__Adjectives__Phrases__has_EORP_meaning(Parser__Nodes__get_aph(imp->then_pn));
{
#line 258 "inform7/Chapter 8/Implications.w"
if ((conclusion_prop == NULL) ||
(World__Permissions__find(candidate, conclusion_prop, TRUE) == NULL)) {
LOGIF(IMPLICATIONS, "IMPOSSIBLE: property not provided\n");
continue;
}
}
#line 241 "inform7/Chapter 8/Implications.w"
;
possession_marker *pom = Properties__get_possession_marker(conclusion_prop);
{
#line 266 "inform7/Chapter 8/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 244 "inform7/Chapter 8/Implications.w"
;
int candidate_qualifies = Calculus__Propositions__test_at_compile_time(imp->if_spec, candidate);
if (candidate_qualifies) {
LOGIF(IMPLICATIONS, "PASS: changing property $Y of $j\n", conclusion_prop, candidate);
{
#line 280 "inform7/Chapter 8/Implications.w"
adjectival_phrase *aph = Properties__EitherOr__get_aph(conclusion_prop);
pcalc_prop *prop = Calculus__Atoms__KIND_new(World__Subjects__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_true_about(prop, candidate, CERTAIN_CE);
return TRUE;
}
#line 250 "inform7/Chapter 8/Implications.w"
;
} else {
LOGIF(IMPLICATIONS, "FAIL: take no action\n");
}
}
#line 225 "inform7/Chapter 8/Implications.w"
;
return FALSE;
}
#line 23 "inform7/Chapter 8/Property Declarations.w"
sentence_handler CANBE_SH_handler =
{ SENTENCE_NT, CANBE_VB, 1, declare_property_can_be };
#line 33 "inform7/Chapter 8/Property Declarations.w"
int forbidden_property_owners_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 41 "inform7/Chapter 8/Property Declarations.w"
*X = -1;
Problems__sentence_problem(_P_(C8PropertyOfKind),
"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 34 "inform7/Chapter 8/Property Declarations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 41 "inform7/Chapter 8/Property Declarations.w"
*X = -1;
Problems__sentence_problem(_P_(C8PropertyOfKind),
"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 35 "inform7/Chapter 8/Property Declarations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 52 "inform7/Chapter 8/Property Declarations.w"
*X = -1;
Problems__sentence_problem(_P_(C8PropertyOfPronoun),
"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 36 "inform7/Chapter 8/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 37 "inform7/Chapter 8/Property Declarations.w"
#line 67 "inform7/Chapter 8/Property Declarations.w"
void declare_property_can_be(parse_node *p) {
parse_node *the_owner = p->down->next;
parse_node *the_list = the_owner->next;
parse_nt_against_word_range(can_be_sentence_object_NTM, the_list->word_ref1, the_list->word_ref2, NULL, NULL);
int either_flag = most_recent_result;
the_list->down = most_recent_result_p;
the_list = the_list->down;
int cname_w1 = -1, cname_w2 = -1;
if (the_list->next) {
cname_w1 = the_list->next->word_ref1; cname_w2 = the_list->next->word_ref2;
}
Parser__Nodes__refine(the_owner, FORBID_CREATION);
{
#line 168 "inform7/Chapter 8/Property Declarations.w"
if (Parser__Nodes__type(the_owner) == WITH_NT) {
Problems__sentence_problem(_P_(C8QualifiedCanBe),
"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 82 "inform7/Chapter 8/Property Declarations.w"
;
int count = list_length(the_list);
{
#line 153 "inform7/Chapter 8/Property Declarations.w"
if ((cname_w1 >= 0) && (count < 3)) {
Problems__sentence_problem(_P_(C8ThisIsEitherOr),
"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 85 "inform7/Chapter 8/Property Declarations.w"
;
int first_w1 = -1, first_w2 = -1;
if (count == 1) { first_w1 = the_list->word_ref1; first_w2 = the_list->word_ref2; }
else { first_w1 = the_list->down->word_ref1; first_w2 = the_list->down->word_ref2; }
{
#line 190 "inform7/Chapter 8/Property Declarations.w"
if ((either_flag) && (count != 2)) {
Problems__sentence_problem(_P_(C8EitherOnThree),
"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 90 "inform7/Chapter 8/Property Declarations.w"
;
int second_w1 = -1, second_w2 = -1;
if (count >= 2) { second_w1 = the_list->down->next->word_ref1; second_w2 = the_list->down->next->word_ref2; }
if (parse_nt_against_word_range(forbidden_property_owners_NTM, the_owner->word_ref1, the_owner->word_ref2, NULL, NULL))
return;
inference_subject *owner_infs = NULL;
{
#line 203 "inform7/Chapter 8/Property Declarations.w"
specification *owner_spec = Parser__Nodes__get_evaluation(the_owner);
if (Specifications__Conditions__is_qualified_DESCRIPTION(owner_spec))
{
#line 237 "inform7/Chapter 8/Property Declarations.w"
Problems__sentence_problem(_P_(C8OwnerTimeDependent),
"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 205 "inform7/Chapter 8/Property Declarations.w"
;
owner_infs = Parser__Nodes__get_subject(the_owner);
if (owner_infs == NULL) {
owner_spec = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, the_owner->word_ref1, the_owner->word_ref2, NULL, NULL))
owner_infs = Kinds__as_subject(Specifications__evaluates_to(most_recent_result_p));
}
kind *K = World__Subjects__domain(owner_infs);
if ((K) && (Kinds__has_properties(K) == FALSE))
{
#line 219 "inform7/Chapter 8/Property Declarations.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__handmade_problem(_P_(C8ValueCantHaveProperties));
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 214 "inform7/Chapter 8/Property Declarations.w"
;
}
#line 98 "inform7/Chapter 8/Property Declarations.w"
;
if (owner_infs == NULL)
{
#line 250 "inform7/Chapter 8/Property Declarations.w"
Problems__sentence_problem(_P_(C8NonObjectCanBe),
"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 99 "inform7/Chapter 8/Property Declarations.w"
;
if (count <= 2)
{
#line 260 "inform7/Chapter 8/Property Declarations.w"
int ew1 = -1, ew2 = -1;
char *error_text = NULL;
ew1 = first_w1; ew2 = first_w2;
property *already = NULL;
if (parse_nt_against_word_range(property_name_NTM, first_w1, first_w2, NULL, NULL)) already = most_recent_result_p;
{
#line 290 "inform7/Chapter 8/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 (parse_nt_against_word_range(spec_type_expression_or_value_NTM, first_w1, first_w2, NULL, NULL)) {
specification *spec = most_recent_result_p;
if (Specifications__species_is(spec, DESCRIPTION_SPC) == FALSE)
error_text = "this already has a meaning";
}
}
}
#line 266 "inform7/Chapter 8/Property Declarations.w"
;
if ((count == 2) && (error_text == NULL)) {
ew1 = second_w1; ew2 = second_w2;
{
#line 304 "inform7/Chapter 8/Property Declarations.w"
if (parse_nt_against_word_range(negated_clause_NTM, ew1, ew2, NULL, NULL)) {
int ep1, ep2;
GET_RW(negated_clause_NTM, 1, ep1, ep2);
property *not_what = NULL;
if (parse_nt_against_word_range(property_name_NTM, ep1, ep2, 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 270 "inform7/Chapter 8/Property Declarations.w"
;
property *alreadybar = NULL;
if (parse_nt_against_word_range(property_name_NTM, ew1, ew2, NULL, NULL)) alreadybar = most_recent_result_p;
{
#line 318 "inform7/Chapter 8/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 (parse_nt_against_word_range(spec_type_expression_or_value_NTM, ew1, ew2, NULL, NULL)) {
specification *spec = most_recent_result_p;
if (Specifications__species_is(spec, DESCRIPTION_SPC) == FALSE)
error_text = "this already has a meaning";
}
}
}
#line 273 "inform7/Chapter 8/Property Declarations.w"
;
}
if (error_text) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, ew1, ew2);
Problems__quote_text(3, error_text);
Problems__handmade_problem(_P_(C8MiscellaneousEOProblem));
Problems__issue_problem_segment(
"In %1, you proposed the new either/or property '%2': but %3.");
Problems__issue_problem_end();
return;
}
}
#line 101 "inform7/Chapter 8/Property Declarations.w"
;
property *prn = NULL;
int already_created_instances = FALSE;
{
#line 340 "inform7/Chapter 8/Property Declarations.w"
if (count <= 2) prn = Properties__EitherOr__obtain(first_w1, first_w2, owner_infs);
else prn = Properties__Valued__Conditions__new(owner_infs, cname_w1, cname_w2, the_list,
&already_created_instances);
Calculus__Propositions__assert_true_about(Calculus__Propositions__to_provide_property(prn),
owner_infs, prevailing_mood);
}
#line 105 "inform7/Chapter 8/Property Declarations.w"
;
if (already_created_instances == FALSE) {
if (count == 2)
{
#line 349 "inform7/Chapter 8/Property Declarations.w"
property *prnbar = Properties__EitherOr__obtain(second_w1, second_w2, owner_infs);
Calculus__Propositions__assert_true_about(Calculus__Propositions__to_provide_property(prnbar),
owner_infs, prevailing_mood);
Properties__EitherOr__make_negations(prn, prnbar);
}
#line 107 "inform7/Chapter 8/Property Declarations.w"
;
if (count >= 3)
{
#line 385 "inform7/Chapter 8/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) {
int pw1, pw2;
if (Parser__Nodes__type(option) == AND_NT) {
pw1 = option->down->word_ref1; pw2 = option->down->word_ref2;
} else {
pw1 = option->word_ref1; pw2 = option->word_ref2;
}
{
#line 407 "inform7/Chapter 8/Property Declarations.w"
if (parse_nt_against_word_range(spec_type_expression_or_value_NTM, pw1, pw2, NULL, NULL)) {
specification *spec = most_recent_result_p;
if ((Specifications__species_is(spec, DESCRIPTION_SPC) == FALSE) &&
(Specifications__Values__is_actual_CONSTANT_construction(spec, CON_property) == FALSE)) {
LOG("Already means: $S\n", spec);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, pw1, pw2);
Problems__quote_spec(3, spec);
Problems__handmade_problem(_P_(C8PropertyAlreadyKnown));
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 394 "inform7/Chapter 8/Property Declarations.w"
;
{
#line 427 "inform7/Chapter 8/Property Declarations.w"
property *already = NULL;
if (parse_nt_against_word_range(property_name_NTM, pw1, pw2, NULL, NULL)) already = most_recent_result_p;
if ((already) && (Properties__is_either_or(already))) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, pw1, pw2);
Problems__handmade_problem(_P_(C8EOClashesWithCondition));
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 395 "inform7/Chapter 8/Property Declarations.w"
;
pcalc_prop *prop = Calculus__Propositions__to_create_something(condition_kind, pw1, pw2);
Calculus__Propositions__assert_true(prop, prevailing_mood);
}
}
#line 108 "inform7/Chapter 8/Property Declarations.w"
;
}
}
#line 115 "inform7/Chapter 8/Property Declarations.w"
int list_length(parse_node *P) {
if (P == NULL) internal_error("Ooops");
if (Parser__Nodes__type(P) == AND_NT)
return list_length(P->down) + list_length(P->down->next);
return 1;
}
#line 131 "inform7/Chapter 8/Property Declarations.w"
int can_be_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 136 "inform7/Chapter 8/Property Declarations.w"
int condition_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 140 "inform7/Chapter 8/Property Declarations.w"
int condition_name_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 145 "inform7/Chapter 8/Property Declarations.w"
int condition_name_innermost_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 149 "inform7/Chapter 8/Property Declarations.w"
#line 459 "inform7/Chapter 8/Property Declarations.w"
property *Parser__Assertions__recursively_declare_properties(parse_node *owner_ref, parse_node *p) {
switch(Parser__Nodes__type(p)) {
case AND_NT:
Parser__Assertions__recursively_declare_properties(owner_ref, p->down);
Parser__Assertions__recursively_declare_properties(owner_ref, p->down->next);
break;
case PROPERTYCALLED_NT:
{
#line 519 "inform7/Chapter 8/Property Declarations.w"
parse_node *kind_ref = p->down;
parse_node *prn_ref = p->down->next;
recursively_call_properties(owner_ref, kind_ref, prn_ref);
return NULL;
}
#line 465 "inform7/Chapter 8/Property Declarations.w"
;
case PROPER_NOUN_NT:
{
#line 477 "inform7/Chapter 8/Property Declarations.w"
if ((parse_nt_against_word_range(k_kind_NTM, p->word_ref1, p->word_ref2, NULL, NULL)) &&
((most_recent_result_p == K_number) || (most_recent_result_p == K_text))) {
Problems__assertion_problem(_P_(C8BareProperty),
"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 = Parser__Nodes__get_subject(owner_ref);
kind *K = World__Subjects__domain(owner_infs);
Kinds__convert_to_enumeration(K); /* if that's possible; does nothing if not */
if ((K) && (Kinds__has_properties(K) == FALSE))
{
#line 498 "inform7/Chapter 8/Property Declarations.w"
if ((Kinds__eq(K, K_action_name)) ||
(Kinds__get_construct(K) == CON_activity) ||
(Kinds__get_construct(K) == CON_rulebook))
Problems__assertion_problem(_P_(C8ValueCantHaveVProperties2),
"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__assertion_problem(_P_(C8ValueCantHaveVProperties),
"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__as_subject(K_object);
}
#line 489 "inform7/Chapter 8/Property Declarations.w"
;
property *prn = Properties__Valued__obtain(p->word_ref1, p->word_ref2);
Calculus__Propositions__assert_true_about(Calculus__Propositions__to_provide_property(prn),
owner_infs, prevailing_mood);
return prn;
}
#line 466 "inform7/Chapter 8/Property Declarations.w"
;
default:
internal_error("Parser__Assertions__recursively_declare_properties on a node of unknown type");
}
return NULL;
}
#line 530 "inform7/Chapter 8/Property Declarations.w"
void recursively_call_properties(parse_node *owner_ref, parse_node *kind_ref, parse_node *prn_ref) {
switch(Parser__Nodes__type(prn_ref)) {
case AND_NT:
recursively_call_properties(owner_ref, kind_ref, prn_ref->down);
recursively_call_properties(owner_ref, kind_ref, prn_ref->down->next);
break;
default:
{
#line 544 "inform7/Chapter 8/Property Declarations.w"
property *prn = Parser__Assertions__recursively_declare_properties(owner_ref, prn_ref);
kind *K = NULL;
{
#line 556 "inform7/Chapter 8/Property Declarations.w"
if (parse_nt_against_word_range(k_kind_NTM, kind_ref->word_ref1, kind_ref->word_ref2, NULL, NULL)) K = most_recent_result_p;
else
{
#line 562 "inform7/Chapter 8/Property Declarations.w"
specification *spec = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, kind_ref->word_ref1, kind_ref->word_ref2, NULL, NULL))
spec = most_recent_result_p;
LOG("Offending SP: $X", spec);
if (Specifications__Storage__is_generic_NONLOCAL_VARIABLE(spec)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, kind_ref->word_ref1, kind_ref->word_ref2);
Problems__handmade_problem(_P_(C8RedundantThatVaries));
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__species_is(spec, DESCRIPTION_SPC)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, kind_ref->word_ref1, kind_ref->word_ref2);
Problems__handmade_problem(_P_(C8PropertyTooSpecific));
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_words(2, kind_ref->word_ref1, kind_ref->word_ref2);
Problems__handmade_problem(_P_(C8PropertyKindUnknown));
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 557 "inform7/Chapter 8/Property Declarations.w"
;
}
#line 546 "inform7/Chapter 8/Property Declarations.w"
;
{
#line 604 "inform7/Chapter 8/Property Declarations.w"
if (Kinds__eq(K, K_value)) {
if (prn == P_variable_initial_value) return;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, kind_ref->word_ref1, kind_ref->word_ref2);
Problems__handmade_problem(_P_(C8PropertyKindVague));
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 547 "inform7/Chapter 8/Property Declarations.w"
;
kind *current_kind = Properties__Valued__kind(prn);
if (current_kind == NULL) Properties__Valued__set_kind(prn, K);
else if (Kinds__eq(current_kind, K) == FALSE)
{
#line 621 "inform7/Chapter 8/Property Declarations.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, kind_ref->word_ref1, kind_ref->word_ref2);
Problems__quote_property(3, prn);
Problems__quote_kind(4, current_kind);
Problems__handmade_problem(_P_(C8PropertyKindClashes));
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 551 "inform7/Chapter 8/Property Declarations.w"
;
}
#line 537 "inform7/Chapter 8/Property Declarations.w"
;
}
}
#line 74 "inform7/Chapter 9/English Inflections.w"
int singular_noun_to_its_indefinite_article_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 78 "inform7/Chapter 9/English Inflections.w"
#line 82 "inform7/Chapter 9/English Inflections.w"
int en_trie_indef_a_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 89 "inform7/Chapter 9/English Inflections.w"
#line 93 "inform7/Chapter 9/English Inflections.w"
int en_trie_indef_b_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 157 "inform7/Chapter 9/English Inflections.w"
#line 161 "inform7/Chapter 9/English Inflections.w"
int en_trie_indef_c_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 215 "inform7/Chapter 9/English Inflections.w"
#line 248 "inform7/Chapter 9/English Inflections.w"
int singular_noun_to_its_plural_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 257 "inform7/Chapter 9/English Inflections.w"
#line 262 "inform7/Chapter 9/English Inflections.w"
int en_trie_plural_uninflected_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 313 "inform7/Chapter 9/English Inflections.w"
#line 317 "inform7/Chapter 9/English Inflections.w"
int en_trie_plural_pronouns_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 340 "inform7/Chapter 9/English Inflections.w"
#line 345 "inform7/Chapter 9/English Inflections.w"
int en_trie_plural_irregular_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 359 "inform7/Chapter 9/English Inflections.w"
#line 364 "inform7/Chapter 9/English Inflections.w"
int en_trie_plural_irregular_inflections_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 375 "inform7/Chapter 9/English Inflections.w"
#line 380 "inform7/Chapter 9/English Inflections.w"
int en_trie_plural_assimilated_classical_inflections_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 405 "inform7/Chapter 9/English Inflections.w"
#line 411 "inform7/Chapter 9/English Inflections.w"
int en_trie_plural_irregular_o_suffixes_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 444 "inform7/Chapter 9/English Inflections.w"
#line 449 "inform7/Chapter 9/English Inflections.w"
int en_trie_plural_regular_inflections_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 528 "inform7/Chapter 9/English Inflections.w"
#line 533 "inform7/Chapter 9/English Inflections.w"
int en_trie_plural_append_s_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 535 "inform7/Chapter 9/English Inflections.w"
#line 653 "inform7/Chapter 9/English Inflections.w"
int verb_conjugation_instructions_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 679 "inform7/Chapter 9/English Inflections.w"
#line 722 "inform7/Chapter 9/English Inflections.w"
int to_have_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 728 "inform7/Chapter 9/English Inflections.w"
#line 812 "inform7/Chapter 9/English Inflections.w"
int to_have_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 817 "inform7/Chapter 9/English Inflections.w"
#line 823 "inform7/Chapter 9/English Inflections.w"
int to_have_present_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 825 "inform7/Chapter 9/English Inflections.w"
#line 860 "inform7/Chapter 9/English Inflections.w"
int to_do_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 864 "inform7/Chapter 9/English Inflections.w"
int to_do_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 875 "inform7/Chapter 9/English Inflections.w"
int to_do_present_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 878 "inform7/Chapter 9/English Inflections.w"
#line 899 "inform7/Chapter 9/English Inflections.w"
int regular_verb_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 905 "inform7/Chapter 9/English Inflections.w"
#line 917 "inform7/Chapter 9/English Inflections.w"
int regular_verb_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 927 "inform7/Chapter 9/English Inflections.w"
#line 935 "inform7/Chapter 9/English Inflections.w"
int regular_verb_present_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 937 "inform7/Chapter 9/English Inflections.w"
#line 941 "inform7/Chapter 9/English Inflections.w"
int to_be_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 945 "inform7/Chapter 9/English Inflections.w"
int to_be_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 955 "inform7/Chapter 9/English Inflections.w"
int to_be_present_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 958 "inform7/Chapter 9/English Inflections.w"
int to_be_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 961 "inform7/Chapter 9/English Inflections.w"
#line 981 "inform7/Chapter 9/English Inflections.w"
int to_be_able_to_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 985 "inform7/Chapter 9/English Inflections.w"
int to_be_able_to_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 995 "inform7/Chapter 9/English Inflections.w"
#line 1022 "inform7/Chapter 9/English Inflections.w"
int to_be_able_to_auxiliary_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1026 "inform7/Chapter 9/English Inflections.w"
int to_be_able_to_auxiliary_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1030 "inform7/Chapter 9/English Inflections.w"
#line 1037 "inform7/Chapter 9/English Inflections.w"
int modal_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1041 "inform7/Chapter 9/English Inflections.w"
int modal_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1053 "inform7/Chapter 9/English Inflections.w"
#line 1081 "inform7/Chapter 9/English Inflections.w"
int contracted_to_be_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1086 "inform7/Chapter 9/English Inflections.w"
int contracted_to_be_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1098 "inform7/Chapter 9/English Inflections.w"
int contracted_to_be_present_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1101 "inform7/Chapter 9/English Inflections.w"
int contracted_to_be_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1104 "inform7/Chapter 9/English Inflections.w"
int contracted_to_be_past_negated_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1107 "inform7/Chapter 9/English Inflections.w"
#line 1121 "inform7/Chapter 9/English Inflections.w"
int contracted_to_have_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1126 "inform7/Chapter 9/English Inflections.w"
int contracted_to_have_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1138 "inform7/Chapter 9/English Inflections.w"
int contracted_to_have_present_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1141 "inform7/Chapter 9/English Inflections.w"
#line 1155 "inform7/Chapter 9/English Inflections.w"
int arent_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1160 "inform7/Chapter 9/English Inflections.w"
int arent_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1167 "inform7/Chapter 9/English Inflections.w"
int arent_present_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1170 "inform7/Chapter 9/English Inflections.w"
int arent_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1173 "inform7/Chapter 9/English Inflections.w"
int arent_perfect_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1176 "inform7/Chapter 9/English Inflections.w"
#line 1186 "inform7/Chapter 9/English Inflections.w"
int informal_negated_modal_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1194 "inform7/Chapter 9/English Inflections.w"
int informal_negated_modal_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1201 "inform7/Chapter 9/English Inflections.w"
int informal_negated_modal_present_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1204 "inform7/Chapter 9/English Inflections.w"
#line 1208 "inform7/Chapter 9/English Inflections.w"
int cant_modal_conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1213 "inform7/Chapter 9/English Inflections.w"
int cant_modal_tabulation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1220 "inform7/Chapter 9/English Inflections.w"
#line 1230 "inform7/Chapter 9/English Inflections.w"
int en_trie_modal_contracted_present_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1241 "inform7/Chapter 9/English Inflections.w"
int en_trie_modal_contracted_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1253 "inform7/Chapter 9/English Inflections.w"
int en_trie_modal_contracted_future_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1265 "inform7/Chapter 9/English Inflections.w"
#line 1314 "inform7/Chapter 9/English Inflections.w"
int en_trie_present_participle_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1320 "inform7/Chapter 9/English Inflections.w"
#line 1328 "inform7/Chapter 9/English Inflections.w"
int en_trie_irregular_present_participle_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1514 "inform7/Chapter 9/English Inflections.w"
#line 1518 "inform7/Chapter 9/English Inflections.w"
int en_trie_irregular_compound_present_participle_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1533 "inform7/Chapter 9/English Inflections.w"
#line 1537 "inform7/Chapter 9/English Inflections.w"
int en_trie_regular_a_present_participle_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1583 "inform7/Chapter 9/English Inflections.w"
#line 1587 "inform7/Chapter 9/English Inflections.w"
int en_trie_regular_b_present_participle_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1591 "inform7/Chapter 9/English Inflections.w"
int en_trie_regular_c_present_participle_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1595 "inform7/Chapter 9/English Inflections.w"
#line 1604 "inform7/Chapter 9/English Inflections.w"
int en_trie_past_participle_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1607 "inform7/Chapter 9/English Inflections.w"
int en_trie_irregular_past_participle_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1760 "inform7/Chapter 9/English Inflections.w"
#line 1768 "inform7/Chapter 9/English Inflections.w"
int en_trie_present_verb_form_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1771 "inform7/Chapter 9/English Inflections.w"
int en_trie_irregular_third_person_present_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1776 "inform7/Chapter 9/English Inflections.w"
#line 1784 "inform7/Chapter 9/English Inflections.w"
int en_trie_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1790 "inform7/Chapter 9/English Inflections.w"
int en_trie_irregular_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2334 "inform7/Chapter 9/English Inflections.w"
int en_trie_irregular_compound_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2350 "inform7/Chapter 9/English Inflections.w"
int en_trie_regular_a_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2397 "inform7/Chapter 9/English Inflections.w"
int en_trie_regular_b_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2402 "inform7/Chapter 9/English Inflections.w"
int en_trie_regular_c_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2407 "inform7/Chapter 9/English Inflections.w"
#line 2430 "inform7/Chapter 9/English Inflections.w"
int pasturise_participle_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2434 "inform7/Chapter 9/English Inflections.w"
int en_trie_pasturise_exceptions_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2898 "inform7/Chapter 9/English Inflections.w"
int en_trie_pasturise_regular_y_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2901 "inform7/Chapter 9/English Inflections.w"
int en_trie_pasturise_regular_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2904 "inform7/Chapter 9/English Inflections.w"
#line 2910 "inform7/Chapter 9/English Inflections.w"
int adjective_to_plural_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2912 "inform7/Chapter 9/English Inflections.w"
int adjective_to_masculine_singular_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2915 "inform7/Chapter 9/English Inflections.w"
int adjective_to_feminine_singular_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2918 "inform7/Chapter 9/English Inflections.w"
int adjective_to_masculine_plural_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2921 "inform7/Chapter 9/English Inflections.w"
int adjective_to_feminine_plural_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 2924 "inform7/Chapter 9/English Inflections.w"
#line 13 "inform7/Chapter 9/Articles and Pronouns.w"
int pronoun_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 9/Articles and Pronouns.w"
int nominative_pronoun_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 9/Articles and Pronouns.w"
int accusative_pronoun_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 9/Articles and Pronouns.w"
#line 33 "inform7/Chapter 9/Articles and Pronouns.w"
int possessive_first_person_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 9/Articles and Pronouns.w"
int possessive_second_person_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 9/Articles and Pronouns.w"
int possessive_third_person_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 9/Articles and Pronouns.w"
#line 52 "inform7/Chapter 9/Articles and Pronouns.w"
int relative_clause_marker_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 54 "inform7/Chapter 9/Articles and Pronouns.w"
#line 58 "inform7/Chapter 9/Articles and Pronouns.w"
int article_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 9/Articles and Pronouns.w"
#line 73 "inform7/Chapter 9/Articles and Pronouns.w"
int definite_article_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 75 "inform7/Chapter 9/Articles and Pronouns.w"
int indefinite_article_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 79 "inform7/Chapter 9/Articles and Pronouns.w"
#line 83 "inform7/Chapter 9/Articles and Pronouns.w"
int optional_definite_article_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 86 "inform7/Chapter 9/Articles and Pronouns.w"
int optional_article_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 90 "inform7/Chapter 9/Articles and Pronouns.w"
int compulsory_article_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 93 "inform7/Chapter 9/Articles and Pronouns.w"
#line 97 "inform7/Chapter 9/Articles and Pronouns.w"
void Text__Languages__remove_the(int *w1, int *w2) {
parse_nt_against_word_range(optional_definite_article_NTM, *w1, *w2, NULL, NULL);
GET_RW(optional_definite_article_NTM, 1, *w1, *w2);
}
void Text__Languages__remove_article(int *w1, int *w2) {
parse_nt_against_word_range(optional_article_NTM, *w1, *w2, NULL, NULL);
GET_RW(optional_article_NTM, 1, *w1, *w2);
}
#line 114 "inform7/Chapter 9/Articles and Pronouns.w"
int non_participles_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 116 "inform7/Chapter 9/Articles and Pronouns.w"
int probable_participle_NTMR(int w1, int w2, int *X, void **XP) {
#line 118 "inform7/Chapter 9/Articles and Pronouns.w"
if (Text__Vocabulary__test_flags(w1, ING_MC)) {
if (parse_nt_against_word_range(non_participles_NTM, w1, w2, NULL, NULL)) return FALSE;
return TRUE;
}
return FALSE;
}
#line 128 "inform7/Chapter 9/Articles and Pronouns.w"
int negated_clause_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 130 "inform7/Chapter 9/Articles and Pronouns.w"
#line 111 "inform7/Chapter 9/Determiners and Quantifiers.w"
quantifier *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 9/Determiners and Quantifiers.w"
void quants_negate_each_other(quantifier *qx, quantifier *qy) {
qx->negated_quant = qy; qy->negated_quant = qx;
}
quantifier *Semantics__Quantifiers__get_negation(quantifier *quant) {
return quant->negated_quant;
}
#line 172 "inform7/Chapter 9/Determiners and Quantifiers.w"
void Semantics__Quantifiers__log(quantifier *quant, int parameter) {
if (quant == NULL) { LOG("<NULL-QUANTIFIER>"); return; }
LOG(quant->log_text, parameter);
}
#line 204 "inform7/Chapter 9/Determiners and Quantifiers.w"
void Semantics__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 9/Determiners and Quantifiers.w"
int Semantics__Quantifiers__is_now_assertable(quantifier *quant) {
return quant->can_be_used_in_now;
}
#line 250 "inform7/Chapter 9/Determiners and Quantifiers.w"
int Semantics__Quantifiers__can_be_used_in_assertions(quantifier *quant) {
return quant->can_be_used_in_assertions;
}
#line 281 "inform7/Chapter 9/Determiners and Quantifiers.w"
determiner *det_new(int not, int pr, int num, quantifier *quant, char *text) {
word_assemblage wa;
if (pr < 0) wa = Text__Words__lit_0();
else wa = Text__Languages__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(
-1, -1, MISCELLANEOUS_LEXE, wa, "determiner", text);
return det;
}
#line 305 "inform7/Chapter 9/Determiners and Quantifiers.w"
int determiner_names_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 327 "inform7/Chapter 9/Determiners and Quantifiers.w"
#line 339 "inform7/Chapter 9/Determiners and Quantifiers.w"
int Semantics__Quantifiers__parse_against_text(int w1, int w2, int *which_P, quantifier **which_quant) {
if (parse_nt_against_word_range(excluded_from_determiners_NTM, w1, w2, NULL, NULL)) return -1;
int not_flag = parse_nt_against_word_range(negated_clause_NTM, w1, w2, NULL, NULL);
if (not_flag) GET_RW(negated_clause_NTM, 1, w1, w2);
*which_P = -1; *which_quant = NULL;
determiner *det;
LOOP_BACKWARDS_OVER(det, determiner) {
int x1;
if ((not_flag) && (det->allows_prefixed_not == FALSE)) continue;
x1 = det_parse_against_text(w1, w2, det, which_P);
if (x1 < 0) continue;
if (not_flag) *which_quant = det->quantifier_meant->negated_quant;
else *which_quant = det->quantifier_meant;
Text__Languages__remove_the(&x1, &w2);
return x1;
}
return -1;
}
#line 374 "inform7/Chapter 9/Determiners and Quantifiers.w"
int determination_of_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 378 "inform7/Chapter 9/Determiners and Quantifiers.w"
#line 392 "inform7/Chapter 9/Determiners and Quantifiers.w"
int excluded_from_determiners_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 394 "inform7/Chapter 9/Determiners and Quantifiers.w"
#line 402 "inform7/Chapter 9/Determiners and Quantifiers.w"
int det_parse_against_text(int x1, int w2, determiner *det, int *which_P) {
int parameter = -1;
if (x1 < 0) return -1;
x1 = Text__Words__parse_as_weakly_initial_text(x1, w2, &(det->text_of_det),
-1, -1, TRUE, FALSE);
if (x1 == -1) return -1;
if (det->takes_number) {
if ((parse_nt_against_word_range(cardinal_number_NTM, x1, x1, NULL, NULL) == FALSE) ||
(Text__unexpectedly_upper_case(x1))) return -1;
x1++;
if (x1 > w2) return -1;
parameter = most_recent_result;
}
if (parse_nt_against_word_range(determination_of_NTM, x1, w2, NULL, NULL)) {
GET_RW(determination_of_NTM, 1, x1, w2);
} else x1 = -1;
if (x1 >= 0) *which_P = parameter;
return x1;
}
#line 428 "inform7/Chapter 9/Determiners and Quantifiers.w"
void Semantics__Quantifiers__make_built_in(void) {
{
#line 469 "inform7/Chapter 9/Determiners and Quantifiers.w"
for_all_quantifier = quant_new("==", 10, FALSE, "ForAll");
not_for_all_quantifier = quant_new("<", 10, FALSE, "NotAll");
exists_quantifier = quant_new(">", 0, FALSE, "Exists");
not_exists_quantifier = 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;
quants_negate_each_other(for_all_quantifier, not_for_all_quantifier);
quants_negate_each_other(exists_quantifier, not_exists_quantifier);
det_new(TRUE, ALL_DET_NAME, FALSE, for_all_quantifier,
"used in conditions: 'if all of the doors are open'");
det_new(FALSE, EACH_DET_NAME, FALSE, for_all_quantifier,
"- see </i>all<i>");
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.'");
det_new(FALSE, NO_DET_NAME, FALSE, not_exists_quantifier,
"opposite of 'all': 'if no door is open...'");
det_new(FALSE, NONE_DET_NAME, FALSE, not_exists_quantifier,
"opposite of 'all of': 'if none of the doors is open...'");
det_new(FALSE, SOME_DET_NAME, FALSE, exists_quantifier, NULL);
det_new(FALSE, ANY_DET_NAME, FALSE, exists_quantifier, NULL);
}
#line 429 "inform7/Chapter 9/Determiners and Quantifiers.w"
;
{
#line 505 "inform7/Chapter 9/Determiners and Quantifiers.w"
all_but_quantifier = quant_new("==", -1, TRUE, "AllBut%d");
not_all_but_quantifier = quant_new("~=", -1, TRUE, "NotAllBut%d");
quants_negate_each_other(all_but_quantifier, not_all_but_quantifier);
det_new(FALSE, ALL_BUT_DET_NAME, TRUE, all_but_quantifier,
"used to count things: 'all but three containers'");
det_new(FALSE, ALL_EXCEPT_DET_NAME, TRUE, all_but_quantifier,
"- see </i>all but<i>");
}
#line 430 "inform7/Chapter 9/Determiners and Quantifiers.w"
;
{
#line 521 "inform7/Chapter 9/Determiners and Quantifiers.w"
almost_all_quantifier = quant_new(">=", 8, FALSE, "Proportion>=80%%");
almost_no_quantifier = quant_new("<", 2, FALSE, "Proportion<20%%");
most_quantifier = quant_new(">", 5, FALSE, "Proportion>50%%");
under_half_quantifier = quant_new("<=", 5, FALSE, "Proportion<=50%%");
quants_negate_each_other(almost_all_quantifier, almost_no_quantifier);
quants_negate_each_other(most_quantifier, under_half_quantifier);
det_new(FALSE, ALMOST_ALL_DET_NAME, FALSE, almost_all_quantifier,
"used in conditions: true if 80 percent or more possibilities work");
det_new(FALSE, ALMOST_NO_DET_NAME, FALSE, almost_no_quantifier,
"used in conditions: true if fewer than 20 percent of possibilities work");
det_new(FALSE, MOST_DET_NAME, FALSE, most_quantifier,
"used in conditions: true if a simple majority of possibilities work");
det_new(FALSE, UNDER_HALF_DET_NAME, FALSE, under_half_quantifier,
"used in conditions: true if fewer than half of possibilities work");
}
#line 431 "inform7/Chapter 9/Determiners and Quantifiers.w"
;
{
#line 559 "inform7/Chapter 9/Determiners and Quantifiers.w"
at_least_quantifier = quant_new(">=", -1, FALSE, "Card>=%d");
at_most_quantifier = quant_new("<=", -1, FALSE, "Card<=%d");
exactly_quantifier = quant_new("==", -1, FALSE, "Card=%d");
less_than_quantifier = quant_new("<", -1, FALSE, "Card<%d");
more_than_quantifier = quant_new(">", -1, FALSE, "Card>%d");
other_than_quantifier = quant_new("~=", -1, FALSE, "Card~=%d");
at_least_quantifier->can_be_used_in_assertions = TRUE;
quants_negate_each_other(at_least_quantifier, less_than_quantifier);
quants_negate_each_other(at_most_quantifier, more_than_quantifier);
quants_negate_each_other(exactly_quantifier, other_than_quantifier);
det_new(FALSE, AT_LEAST_DET_NAME, TRUE, at_least_quantifier,
"used to count things: 'at least five doors'");
det_new(FALSE, AT_MOST_DET_NAME, TRUE, at_most_quantifier,
"- see </i>at least<i>");
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");
det_new(TRUE, FEWER_THAN_DET_NAME, TRUE, less_than_quantifier,
"pedantic way to say </i>less than<i> when counting");
det_new(TRUE, LESS_THAN_DET_NAME, TRUE, less_than_quantifier,
"- see </i>more than<i>");
det_new(TRUE, MORE_THAN_DET_NAME, TRUE, more_than_quantifier,
"used to count things: 'more than three rooms'");
det_new(TRUE, GREATER_THAN_DET_NAME, TRUE, more_than_quantifier,
"used to count things: 'greater than three rooms'");
det_new(FALSE, OTHER_THAN_DET_NAME, TRUE, other_than_quantifier, NULL);
det_new(FALSE, -1, TRUE, at_least_quantifier, NULL);
}
#line 432 "inform7/Chapter 9/Determiners and Quantifiers.w"
;
}
#line 594 "inform7/Chapter 9/Determiners and Quantifiers.w"
int 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 339 "inform7/Chapter 9/Binary Predicates.w"
bp_term_details Semantics__BPs__Terms__new(inference_subject *infs) {
bp_term_details bptd;
bptd.word_ref1 = -1; bptd.word_ref2 = -1;
bptd.function_of_other = NULL;
bptd.implies_infs = infs;
bptd.implies_kind = NULL;
bptd.index_term_as = NULL;
return bptd;
}
#line 352 "inform7/Chapter 9/Binary Predicates.w"
bp_term_details Semantics__BPs__Terms__full_new(inference_subject *infs, kind *K,
int c1, int c2, i6_schema *f) {
bp_term_details bptd = Semantics__BPs__Terms__new(infs);
bptd.implies_kind = K;
bptd.word_ref1 = c1; bptd.word_ref2 = c2;
bptd.function_of_other = f;
return bptd;
}
#line 365 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Terms__set_domain(bp_term_details *bptd, kind *K) {
if (bptd == NULL) internal_error("no BPTD");
bptd->implies_kind = K;
bptd->implies_infs = Kinds__as_subject(K);
}
#line 374 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Terms__set_function(bp_term_details *bptd, i6_schema *f) {
if (bptd == NULL) internal_error("no BPTD");
bptd->function_of_other = f;
}
i6_schema *Semantics__BPs__Terms__get_function(bp_term_details *bptd) {
if (bptd == NULL) internal_error("no BPTD");
return bptd->function_of_other;
}
#line 387 "inform7/Chapter 9/Binary Predicates.w"
kind *Semantics__BPs__kind(binary_predicate *bp) {
if (bp == R_equality) return Kinds__binary_construction(CON_relation, K_value, K_value);
kind *K0 = bptd_kind(&(bp->term_details[0]));
kind *K1 = bptd_kind(&(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 399 "inform7/Chapter 9/Binary Predicates.w"
kind *bptd_kind(bp_term_details *bptd) {
if (bptd == NULL) return NULL;
if (bptd->implies_kind) return bptd->implies_kind;
return World__Subjects__domain(bptd->implies_infs);
}
#line 408 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Terms__details_index(bp_term_details *bptd) {
if (bptd->index_term_as) { INDEX("%s", bptd->index_term_as); return; }
int w1 = -1, w2 = -1;
if (bptd->implies_infs) World__Subjects__get_name_text(bptd->implies_infs, &w1, &w2);
if (w1 >= 0) Text__print_text_to_stream(w1, w2, ifl); else INDEX("--");
}
#line 421 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Terms__add_as_call_parameter(OUTPUT_STREAM, ph_stack_frame *phsf, bp_term_details bptd) {
kind *K = bptd_kind(&bptd);
kind *PK = K;
if ((PK == NULL) || (Kinds__lt(PK, K_object))) PK = K_object;
local_variable *lvar = Code__LocalVariables__add_call_parameter(phsf,
bptd.word_ref1, bptd.word_ref2, PK);
if (Kinds__lt(K, K_object))
WRITE(" if (~~(%s ofclass %s)) rfalse;\n",
Code__LocalVariables__lvalue(lvar), Kinds__I6_classname(K));
}
#line 435 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__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 463 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate *Semantics__BPs__make_equality(void) {
binary_predicate *bp = make_single_BP(EQUALITY_KBP,
Semantics__BPs__Terms__new(NULL), Semantics__BPs__Terms__new(NULL),
"is", NULL, NULL, NULL,
Text__Languages__wording(relation_names_NTM, EQUALITY_RELATION_NAME));
bp->reversal = bp; bp->right_way_round = TRUE;
return bp;
}
#line 484 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate *Semantics__BPs__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 = make_single_BP(family, left_term, right_term, name,
pn, mtf, tf, source_name);
bpr = make_single_BP(family, right_term, left_term, namer,
NULL, NULL, NULL, Text__Words__lit_0());
bp->reversal = bpr; bpr->reversal = bp;
bp->right_way_round = TRUE; bpr->right_way_round = FALSE;
if (Text__Words__nonempty(source_name))
Semantics__Nouns__ExcerptMeanings__register_assemblage(
MISCELLANEOUS_MC, RELATION_SMC,
Text__Languages__merge(relation_name_formal_NTM, 0, source_name),
STORE_POINTER_binary_predicate(bp));
return bp;
}
#line 518 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate *Semantics__BPs__make_pair_sketchily(word_assemblage wa, int f) {
char *name = Text__Vocabulary__get_exemplar(Text__Words__first_word(&wa), FALSE);
binary_predicate *bp =
Semantics__BPs__make_pair(EXPLICIT_KBP,
Semantics__BPs__Terms__new(NULL), Semantics__BPs__Terms__new(NULL),
name, NULL, NULL, NULL, NULL, wa);
bp->form_of_relation = f;
bp->reversal->form_of_relation = f;
return bp;
}
#line 541 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate *make_single_BP(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_w1 = -1; bp->condition_defn_w2 = -1;
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_w1 = -1; bp->property_pending_w2 = -1;
bp->relates_values_not_objects = FALSE;
bp->knowledge_about_bp =
World__Subjects__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 595 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__Subjects__get_name_text(inference_subject *from, int *w1, int *w2) {
/* nameless */
}
general_pointer Semantics__BPs__Subjects__new_permission_granted(inference_subject *from) {
return NULL_GENERAL_POINTER;
}
void Semantics__BPs__Subjects__make_adj_const_domain(inference_subject *infs,
instance *nc, property *prn) {
}
void Semantics__BPs__Subjects__complete_model(inference_subject *infs) {
int domain_size = NUMBER_CREATED(inference_subject);
binary_predicate *bp = World__Subjects__as_bp(infs);
if (Semantics__BPs__store_dynamically(bp)) return; /* handled at run-time instead */
if ((Semantics__BPs__get_form_of_relation(bp) == Relation_Equiv) && (bp->right_way_round)) {
Semantics__Relations__equivalence_relation_make_singleton_partitions(bp, domain_size);
inference *i;
POSITIVE_KNOWLEDGE_LOOP(i, Semantics__BPs__as_subject(bp), ARBITRARY_RELATION_INF) {
inference_subject *infs0, *infs1;
World__Inferences__get_references(i, &infs0, &infs1);
Semantics__Relations__equivalence_relation_merge_classes(bp, domain_size,
infs0->allocation_id, infs1->allocation_id);
}
Semantics__Relations__equivalence_relation_add_properties(bp);
}
}
void Semantics__BPs__Subjects__check_model(inference_subject *infs) {
binary_predicate *bp = World__Subjects__as_bp(infs);
if ((bp->right_way_round) &&
((bp->form_of_relation == Relation_OtoO) ||
(bp->form_of_relation == Relation_Sym_OtoO)))
Semantics__Relations__check_1to1_relation(bp);
}
void Semantics__BPs__Subjects__write_element_of_condition(inference_subject *infs, char *cond) {
internal_error("BP in runtime match condition");
}
int Semantics__BPs__Subjects__compile_all(OUTPUT_STREAM) {
return FALSE;
}
void Semantics__BPs__Subjects__compile(OUTPUT_STREAM, inference_subject *infs) {
binary_predicate *bp = World__Subjects__as_bp(infs);
if (bp->right_way_round) {
if (Semantics__BPs__store_dynamically(bp)) {
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "InitialiseRelation_%d", bp->allocation_id);
OUT = Code__Routines__begin(OUT, i6_routine_identifier);
inference *i;
POSITIVE_KNOWLEDGE_LOOP(i, Semantics__BPs__as_subject(bp), ARBITRARY_RELATION_INF) {
specification *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__compile(OUT, spec0);
WRITE(",");
Specifications__compile(OUT, spec1);
WRITE(");\n");
}
OUT = Code__Routines__end(OUT);
} else {
if ((bp->form_of_relation == Relation_VtoV) ||
(bp->form_of_relation == Relation_Sym_VtoV))
Semantics__Relations__compile_vtov_storage(OUT, bp);
}
}
}
#line 670 "inform7/Chapter 9/Binary Predicates.w"
void log_bp_term_details(bp_term_details *bptd, int i) {
LOG(" function(%d): $i\n", i, bptd->function_of_other);
if (bptd->word_ref1 >= 0) LOG(" term %d is '$W'\n", i, bptd->word_ref1, bptd->word_ref2);
if (bptd->implies_infs) {
int w1, w2;
World__Subjects__get_name_text(bptd->implies_infs, &w1, &w2);
if (w1 >= 0) LOG(" term %d has domain $W\n", i, w1, w2);
}
}
void Semantics__BPs__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",
bp_form_to_text(bp));
for (i=0; i<2; i++) log_bp_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 700 "inform7/Chapter 9/Binary Predicates.w"
int relation_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 701 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate *bp;
LOOP_OVER(bp, binary_predicate)
if (Text__Words__compare_with_range(&(bp->relation_name), w1, w2)) {
*XP = bp; return TRUE;
}
return FALSE;
}
#line 712 "inform7/Chapter 9/Binary Predicates.w"
char *Semantics__BPs__get_log_name(binary_predicate *bp) {
return bp->debugging_log_name;
}
#line 719 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__get_form_of_relation(binary_predicate *bp) {
return bp->form_of_relation;
}
int Semantics__BPs__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 *bp_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";
}
}
#line 746 "inform7/Chapter 9/Binary Predicates.w"
kind *Semantics__BPs__term_kind(binary_predicate *bp, int t) {
return bptd_kind(&(bp->term_details[t]));
}
i6_schema *Semantics__BPs__get_term_as_function_of_other(binary_predicate *bp, int t) {
return bp->term_details[t].function_of_other;
}
#line 756 "inform7/Chapter 9/Binary Predicates.w"
binary_predicate *Semantics__BPs__get_reversal(binary_predicate *bp) {
return bp->reversal;
}
int Semantics__BPs__is_the_wrong_way_round(binary_predicate *bp) {
if (bp->right_way_round == FALSE) return TRUE;
return FALSE;
}
#line 767 "inform7/Chapter 9/Binary Predicates.w"
i6_schema *Semantics__BPs__get_test_function(binary_predicate *bp) {
return bp->test_function;
}
int Semantics__BPs__can_be_made_true_at_runtime(binary_predicate *bp) {
if ((bp->make_true_function) ||
(bp->reversal->make_true_function)) return TRUE;
return FALSE;
}
#line 784 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__allow_arbitrary_assertions(binary_predicate *bp) {
return bp->arbitrary;
}
int Semantics__BPs__store_dynamically(binary_predicate *bp) {
return bp->dynamic_memory;
}
int Semantics__BPs__relates_values_not_objects(binary_predicate *bp) {
return bp->relates_values_not_objects;
}
inference_subject *Semantics__BPs__as_subject(binary_predicate *bp) {
return bp->knowledge_about_bp;
}
#line 800 "inform7/Chapter 9/Binary Predicates.w"
property *Semantics__BPs__get_i6_storage_property(binary_predicate *bp) {
return bp->i6_storage_property;
}
int Semantics__BPs__allows_function_simplification(binary_predicate *bp) {
return bp->allow_function_simplification;
}
void Semantics__BPs__mark_as_needed(binary_predicate *bp) {
bp->record_needed = TRUE;
}
#line 813 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__set_comparison_details(binary_predicate *bp,
int sign, property *prn) {
bp->comparison_sign = sign; bp->comparative_property = prn;
}
#line 830 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__write_optimised_loop_schema(i6_schema *sch, binary_predicate *bp) {
if (bp == NULL) return FALSE;
{
#line 843 "inform7/Chapter 9/Binary Predicates.w"
if (bp->loop_parent_optimisation_ranger) {
Code__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 832 "inform7/Chapter 9/Binary Predicates.w"
;
{
#line 860 "inform7/Chapter 9/Binary Predicates.w"
if (bp->loop_parent_optimisation_proviso) {
Code__Schemas__modify(sch,
"objectloop (*1 in *2) if (%s(*1)==parent(*1))",
bp->loop_parent_optimisation_proviso);
return TRUE;
}
}
#line 833 "inform7/Chapter 9/Binary Predicates.w"
;
return FALSE;
}
#line 873 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__make_built_in(void) {
Calculus__Relations__Equality__create_initial_stock();
Properties__Valued__Relations__Provision__create_initial_stock();
Semantics__Relations__Universal__create_initial_stock();
Calculus__Relations__Quasinumeric__create_initial_stock();
Plugins__Spatial__Relations__create_initial_stock();
Plugins__Map__Relations__create_initial_stock();
Properties__Valued__Relations__Setting__create_initial_stock();
Properties__Valued__Relations__Same__create_initial_stock();
Properties__Valued__Relations__Comparative__create_initial_stock();
Data__Tables__Relations__create_initial_stock();
Semantics__Relations__Explicit__create_initial_stock();
}
#line 890 "inform7/Chapter 9/Binary Predicates.w"
void Semantics__BPs__make_built_in_further(void) {
Calculus__Relations__Equality__create_second_stock();
Properties__Valued__Relations__Provision__create_second_stock();
Semantics__Relations__Universal__create_second_stock();
Calculus__Relations__Quasinumeric__create_second_stock();
Plugins__Spatial__Relations__create_second_stock();
Plugins__Map__Relations__create_second_stock();
Properties__Valued__Relations__Setting__create_second_stock();
Properties__Valued__Relations__Same__create_second_stock();
Properties__Valued__Relations__Comparative__create_second_stock();
Data__Tables__Relations__create_second_stock();
Semantics__Relations__Explicit__create_second_stock();
}
#line 910 "inform7/Chapter 9/Binary Predicates.w"
int Semantics__BPs__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__Relations__Equality__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case PROVISION_KBP: result = Properties__Valued__Relations__Provision__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case UNIVERSAL_KBP: result = Semantics__Relations__Universal__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case QUASINUMERIC_KBP: result = Calculus__Relations__Quasinumeric__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case SPATIAL_KBP: result = Plugins__Spatial__Relations__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case MAP_CONNECTING_KBP: result = Plugins__Map__Relations__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case PROPERTY_SETTING_KBP: result = Properties__Valued__Relations__Setting__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case PROPERTY_SAME_KBP: result = Properties__Valued__Relations__Same__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case PROPERTY_COMPARISON_KBP: result = Properties__Valued__Relations__Comparative__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case LISTED_IN_KBP: result = Data__Tables__Relations__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case EXPLICIT_KBP: result = Semantics__Relations__Explicit__typecheck(bp, kinds_of_terms, kinds_required, tck); break;
default: internal_error("typechecked unknown KBP");
}
return result;
}
int Semantics__BPs__assert(binary_predicate *bp,
inference_subject *subj0, specification *spec0, inference_subject *subj1, specification *spec1) {
int success = FALSE;
switch (bp->relation_family) {
case EQUALITY_KBP: success = Calculus__Relations__Equality__assert(bp, subj0, spec0, subj1, spec1); break;
case PROVISION_KBP: success = Properties__Valued__Relations__Provision__assert(bp, subj0, spec0, subj1, spec1); break;
case UNIVERSAL_KBP: success = Semantics__Relations__Universal__assert(bp, subj0, spec0, subj1, spec1); break;
case QUASINUMERIC_KBP: success = Calculus__Relations__Quasinumeric__assert(bp, subj0, spec0, subj1, spec1); break;
case SPATIAL_KBP: success = Plugins__Spatial__Relations__assert(bp, subj0, spec0, subj1, spec1); break;
case MAP_CONNECTING_KBP: success = Plugins__Map__Relations__assert(bp, subj0, spec0, subj1, spec1); break;
case PROPERTY_SETTING_KBP: success = Properties__Valued__Relations__Setting__assert(bp, subj0, spec0, subj1, spec1); break;
case PROPERTY_SAME_KBP: success = Properties__Valued__Relations__Same__assert(bp, subj0, spec0, subj1, spec1); break;
case PROPERTY_COMPARISON_KBP: success = Properties__Valued__Relations__Comparative__assert(bp, subj0, spec0, subj1, spec1); break;
case LISTED_IN_KBP: success = Data__Tables__Relations__assert(bp, subj0, spec0, subj1, spec1); break;
case EXPLICIT_KBP: success = Semantics__Relations__Explicit__assert(bp, subj0, spec0, subj1, spec1); break;
default: internal_error("asserted unknown KBP");
}
return success;
}
i6_schema *Semantics__BPs__get_i6_schema(int task, binary_predicate *bp, annotated_i6_schema *asch) {
int success = FALSE;
switch (bp->relation_family) {
case EQUALITY_KBP: success = Calculus__Relations__Equality__compile(task, bp, asch); break;
case PROVISION_KBP: success = Properties__Valued__Relations__Provision__compile(task, bp, asch); break;
case UNIVERSAL_KBP: success = Semantics__Relations__Universal__compile(task, bp, asch); break;
case QUASINUMERIC_KBP: success = Calculus__Relations__Quasinumeric__compile(task, bp, asch); break;
case SPATIAL_KBP: success = Plugins__Spatial__Relations__compile(task, bp, asch); break;
case MAP_CONNECTING_KBP: success = Plugins__Map__Relations__compile(task, bp, asch); break;
case PROPERTY_SETTING_KBP: success = Properties__Valued__Relations__Setting__compile(task, bp, asch); break;
case PROPERTY_SAME_KBP: success = Properties__Valued__Relations__Same__compile(task, bp, asch); break;
case PROPERTY_COMPARISON_KBP: success = Properties__Valued__Relations__Comparative__compile(task, bp, asch); break;
case LISTED_IN_KBP: success = Data__Tables__Relations__compile(task, bp, asch); break;
case EXPLICIT_KBP: success = Semantics__Relations__Explicit__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 Semantics__BPs__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
int success = FALSE;
switch (bp->relation_family) {
case EQUALITY_KBP: success = Calculus__Relations__Equality__describe_for_problems(OUT, bp); break;
case PROVISION_KBP: success = Properties__Valued__Relations__Provision__describe_for_problems(OUT, bp); break;
case UNIVERSAL_KBP: success = Semantics__Relations__Universal__describe_for_problems(OUT, bp); break;
case QUASINUMERIC_KBP: success = Calculus__Relations__Quasinumeric__describe_for_problems(OUT, bp); break;
case SPATIAL_KBP: success = Plugins__Spatial__Relations__describe_for_problems(OUT, bp); break;
case MAP_CONNECTING_KBP: success = Plugins__Map__Relations__describe_for_problems(OUT, bp); break;
case PROPERTY_SETTING_KBP: success = Properties__Valued__Relations__Setting__describe_for_problems(OUT, bp); break;
case PROPERTY_SAME_KBP: success = Properties__Valued__Relations__Same__describe_for_problems(OUT, bp); break;
case PROPERTY_COMPARISON_KBP: success = Properties__Valued__Relations__Comparative__describe_for_problems(OUT, bp); break;
case LISTED_IN_KBP: success = Data__Tables__Relations__describe_for_problems(OUT, bp); break;
case EXPLICIT_KBP: success = Semantics__Relations__Explicit__describe_for_problems(OUT, bp); break;
default: internal_error("found unknown KBP");
}
if (success == NOT_APPLICABLE) return;
if (success == FALSE) {
if (Text__Words__nonempty(bp->relation_name)) {
WRITE("the ");
Text__Words__copy_to_stream(OUT, &(bp->relation_name));
} else WRITE("a");
WRITE(" relation");
}
kind *K0 = Semantics__BPs__term_kind(bp, 0); if (K0 == NULL) K0 = K_object;
kind *K1 = Semantics__BPs__term_kind(bp, 1); if (K1 == NULL) K1 = K_object;
WRITE(" (between ");
if (Kinds__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 9/Relations.w"
int relation_names_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 89 "inform7/Chapter 9/Relations.w"
#line 109 "inform7/Chapter 9/Relations.w"
int relates_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 116 "inform7/Chapter 9/Relations.w"
*X = FALSE;
Problems__sentence_problem(_P_(C9RelationExists),
"that relation already exists",
"and cannot have its definition amended now.");
}
#line 110 "inform7/Chapter 9/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 9/Relations.w"
#line 124 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__parse_new(parse_node *PN) {
int rw1, rw2;
rw1 = PN->down->next->word_ref1; rw2 = PN->down->next->word_ref2;
parse_nt_against_word_range(relates_sentence_subject_NTM, rw1, rw2, NULL, NULL);
if (most_recent_result) {
binary_predicate *bp = Semantics__BPs__make_pair_sketchily(
Text__Words__from_range(rw1, rw2), Relation_OtoO);
Parser__Nodes__set_new_relation_here(PN->down->next, bp);
}
}
#line 148 "inform7/Chapter 9/Relations.w"
sentence_handler NEW_RELATION_SH_handler =
{ SENTENCE_NT, NEW_RELATION_VB, 1, parse_new_relation_further };
void parse_new_relation_further(parse_node *PN) {
int rw1 = -1, rw2 = -1; /* relation name */
int f1 = -1, f2 = -1; /* left term declaration, before "to" */
int s1 = -1, s2 = -1; /* right term declaration, after "to" */
rw1 = PN->down->next->word_ref1; rw2 = PN->down->next->word_ref2;
f1 = PN->down->next->next->word_ref1; f2 = PN->down->next->next->word_ref2;
s1 = PN->down->next->next->next->word_ref1; s2 = PN->down->next->next->next->word_ref2;
binary_predicate *bp = Parser__Nodes__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 */
int left_unique = NOT_APPLICABLE, /* |TRUE| for one, |FALSE| for various, */
right_unique = NOT_APPLICABLE, /* ...or |NOT_APPLICABLE| for unspecified */
condition_w1 = -1, condition_w2 = -1, /* text of test condition if any */
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");
{
#line 304 "inform7/Chapter 9/Relations.w"
LOGIF(RELATION_DEFINITIONS,
"Relation definition of $W: left term: '$W', right term: '$W'\n",
rw1, rw2, f1, f2, s1, s2);
int left_cw1 = -1, left_cw2 = -1, /* left term "calling" name */
right_cw1 = -1, right_cw2 = -1; /* right term "calling" name */
parse_nt_against_word_range(relates_sentence_left_object_NTM, f1, f2, NULL, NULL);
int left_bitmap = most_recent_result;
if (left_bitmap & CALLED_RBIT) GET_RW(relates_sentence_left_object_NTM, 1, left_cw1, left_cw2);
GET_RW(relation_term_basic_NTM, 1, f1, f2);
parse_nt_against_word_range(relates_sentence_right_object_NTM, s1, s2, NULL, NULL);
int right_bitmap = most_recent_result;
if (right_bitmap & CALLED_RBIT)
GET_RW(relation_term_right_named_NTM, 1, right_cw1, right_cw2);
GET_RW(relation_term_basic_NTM, 1, s1, s2);
if (right_bitmap & WHEN_RBIT)
GET_RW(relates_sentence_right_object_NTM, 1, condition_w1, condition_w2);
{
#line 365 "inform7/Chapter 9/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__sentence_problem(_P_(C9FRFUnavailable),
"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 325 "inform7/Chapter 9/Relations.w"
;
{
#line 388 "inform7/Chapter 9/Relations.w"
if (right_bitmap & WHEN_RBIT) {
if ((left_unique != NOT_APPLICABLE) || (right_unique != NOT_APPLICABLE)) {
Problems__sentence_problem(_P_(C9OneOrVariousWithWhen),
"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 326 "inform7/Chapter 9/Relations.w"
;
{
#line 404 "inform7/Chapter 9/Relations.w"
if ((left_bitmap & CALLED_RBIT) || (right_bitmap & CALLED_RBIT))
calling_made = TRUE;
}
#line 327 "inform7/Chapter 9/Relations.w"
;
{
#line 413 "inform7/Chapter 9/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__sentence_problem(_P_(C9BothOneAndMany),
"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 328 "inform7/Chapter 9/Relations.w"
;
{
#line 448 "inform7/Chapter 9/Relations.w"
if (condition_w1 == -1) {
if ((left_unique == FALSE) && (left_cw1 >= 0)) {
Problems__sentence_problem(_P_(C9CantCallLeft),
"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) && (right_cw1 >= 0)) {
Problems__sentence_problem(_P_(C9CantCallRight),
"the right-hand term of this relation is not unique",
"so you cannot assign a name to it using 'called'.");
return;
}
if ((left_cw1 >= 0) && (right_cw1 >= 0)) {
Problems__sentence_problem(_P_(C9CantCallBoth),
"the relation has to have the same name on both sides",
"so it should be 'called' something even-handed: for instance, "
"'Marriage relates one person to another (called the spouse).' "
"rather than 'Marriage relates one man (called the husband) to "
"one woman (called the wife).'");
return;
}
if ((symmetric == FALSE) && (left_unique) && (right_unique) && (right_cw1 >= 0)) {
Problems__sentence_problem(_P_(C9OneToOneMiscalled),
"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 329 "inform7/Chapter 9/Relations.w"
;
{
#line 491 "inform7/Chapter 9/Relations.w"
if (parse_relation_term_type(f1, f2, &left_kind, "left") == FALSE) return;
if (symmetric) {
right_kind = left_kind;
} else {
if (parse_relation_term_type(s1, s2, &right_kind, "right") == FALSE) return;
}
rvno = TRUE;
if ((Kinds__le(left_kind, K_object)) &&
(Kinds__le(right_kind, K_object))) rvno = FALSE;
if (condition_w1 == -1) {
if ((Kinds__lt(left_kind, K_object) == FALSE) &&
(check_finite_range(left_kind) == FALSE)) dynamic = TRUE;
if ((Kinds__lt(right_kind, K_object) == FALSE) &&
(symmetric == FALSE) &&
(check_finite_range(right_kind) == FALSE)) dynamic = TRUE;
}
}
#line 330 "inform7/Chapter 9/Relations.w"
;
if (left_unique == NOT_APPLICABLE) {
left_unique = FALSE;
if ((left_cw1 >= 0) || (right_unique == FALSE)) left_unique = TRUE;
}
if (right_unique == NOT_APPLICABLE) {
right_unique = FALSE;
if ((right_cw1 >= 0) || (left_unique == FALSE)) right_unique = TRUE;
}
if (condition_w1 == -1)
{
#line 517 "inform7/Chapter 9/Relations.w"
if (left_cw1 >= 0) {
prn = Properties__Valued__obtain_within_kind(left_cw1, left_cw2, left_kind);
if (prn == NULL) return;
} else if (right_cw1 >= 0) {
prn = Properties__Valued__obtain_within_kind(right_cw1, right_cw2, right_kind);
if (prn == NULL) return;
} else {
prn = Properties__Valued__obtain_within_kind(rw1, rw2, 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__le(PK, K_object) == FALSE) Properties__Valued__set_kind(prn, PK);
if (storage_kind) storage_infs = Kinds__as_subject(storage_kind);
else storage_infs = NULL;
if (Kinds__le(storage_kind, K_object) == FALSE) bp->storage_kind = storage_kind;
if (((left_unique) || (right_unique)) && (PK) &&
(Kinds__le(PK, K_object) == FALSE))
Properties__Valued__now_used_for_non_typesafe_relation(prn);
}
#line 341 "inform7/Chapter 9/Relations.w"
;
{
#line 348 "inform7/Chapter 9/Relations.w"
bp_term_details left_bptd, right_bptd;
inference_subject *left_infs = NULL, *right_infs = NULL;
if (left_kind) left_infs = Kinds__as_subject(left_kind);
if (right_kind) right_infs = Kinds__as_subject(right_kind);
left_bptd = Semantics__BPs__Terms__full_new(left_infs, left_kind, left_cw1, left_cw2, NULL);
right_bptd = Semantics__BPs__Terms__full_new(right_infs, right_kind, right_cw1, right_cw2, 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 343 "inform7/Chapter 9/Relations.w"
;
}
#line 182 "inform7/Chapter 9/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 (condition_w1 >= 0)
{
#line 681 "inform7/Chapter 9/Relations.w"
bp->form_of_relation = Relation_ByRoutine;
bp->test_function = Code__Schemas__new("(Relation_%d(*1,*2))", bp->allocation_id);
bp->condition_defn_w1 = condition_w1; bp->condition_defn_w2 = condition_w2;
}
#line 193 "inform7/Chapter 9/Relations.w"
else if (equivalence)
{
#line 659 "inform7/Chapter 9/Relations.w"
bp->form_of_relation = Relation_Equiv;
bp->arbitrary = TRUE;
provide_prn = TRUE;
if (Kinds__le(storage_kind, K_object)) {
bp->test_function = Code__Schemas__new("(*1.%s == *2.%s)", i6_prn_name, i6_prn_name);
bp->make_true_function = Code__Schemas__new("Relation_NowEquiv(*1,%s,*2)", i6_prn_name);
bp->make_false_function = Code__Schemas__new("Relation_NowNEquiv(*1,%s,*2)", i6_prn_name);
} else {
bp->test_function =
Code__Schemas__new("(GProperty(%k, *1, %s) == GProperty(%k, *2, %s))",
storage_kind, i6_prn_name, storage_kind, i6_prn_name);
bp->make_true_function =
Code__Schemas__new("Relation_NowEquivV(*1,*2,%k,%s)", storage_kind, i6_prn_name);
bp->make_false_function =
Code__Schemas__new("Relation_NowNEquivV(*1,*2,%k,%s)", storage_kind, i6_prn_name);
}
Properties__Valued__set_kind(prn, K_number);
}
#line 194 "inform7/Chapter 9/Relations.w"
else if (left_unique) {
if (right_unique) {
if (symmetric)
{
#line 629 "inform7/Chapter 9/Relations.w"
bp->form_of_relation = Relation_Sym_OtoO;
provide_prn = TRUE;
if (Kinds__le(storage_kind, K_object)) {
bp->make_true_function = Code__Schemas__new("Relation_NowS1to1(*2,%s,*1)", i6_prn_name);
bp->make_false_function = Code__Schemas__new("Relation_NowSN1to1(*2,%s,*1)", i6_prn_name);
} else {
bp->make_true_function = Code__Schemas__new("Relation_NowS1to1V(*2,*1,%k,%s)",
storage_kind, i6_prn_name);
bp->make_false_function = Code__Schemas__new("Relation_NowSN1to1V(*2,*1,%k,%s)",
storage_kind, i6_prn_name);
}
}
#line 197 "inform7/Chapter 9/Relations.w"
else
{
#line 569 "inform7/Chapter 9/Relations.w"
bp->form_of_relation = Relation_OtoO;
provide_prn = TRUE;
if (Kinds__le(storage_kind, K_object)) {
bp->make_true_function = Code__Schemas__new("Relation_Now1to1(*2,%s,*1)", i6_prn_name);
bp->make_false_function = Code__Schemas__new("Relation_NowN1toV(*2,%s,*1)", i6_prn_name);
} else {
bp->make_true_function = Code__Schemas__new("Relation_Now1to1V(*2,*1,%k,%s)",
storage_kind, i6_prn_name);
bp->make_false_function = Code__Schemas__new("Relation_NowN1toVV(*2,*1,%k,%s)",
storage_kind, i6_prn_name);
}
}
#line 198 "inform7/Chapter 9/Relations.w"
;
} else
{
#line 584 "inform7/Chapter 9/Relations.w"
bp->form_of_relation = Relation_OtoV;
provide_prn = TRUE;
if (Kinds__le(storage_kind, K_object)) {
bp->make_true_function = Code__Schemas__new("*2.%s = *1", i6_prn_name);
bp->make_false_function = Code__Schemas__new("Relation_NowN1toV(*2,%s,*1)", i6_prn_name);
} else {
bp->make_true_function = Code__Schemas__new("WriteGProperty(%k, *2, %s, *1)",
storage_kind, i6_prn_name);
bp->make_false_function = Code__Schemas__new("Relation_NowN1toVV(*2,*1,%k,%s)",
storage_kind, i6_prn_name);
}
}
#line 199 "inform7/Chapter 9/Relations.w"
;
} else {
if (right_unique)
{
#line 599 "inform7/Chapter 9/Relations.w"
bp->form_of_relation = Relation_VtoO;
provide_prn = TRUE;
if (Kinds__le(storage_kind, K_object)) {
bp->make_true_function = Code__Schemas__new("*1.%s = *2", i6_prn_name);
bp->make_false_function = Code__Schemas__new("Relation_NowN1toV(*1,%s,*2)", i6_prn_name);
} else {
bp->make_true_function = Code__Schemas__new("WriteGProperty(%k, *1, %s, *2)",
storage_kind, i6_prn_name);
bp->make_false_function = Code__Schemas__new("Relation_NowN1toVV(*1,*2,%k,%s)",
storage_kind, i6_prn_name);
}
}
#line 201 "inform7/Chapter 9/Relations.w"
else if (symmetric)
{
#line 645 "inform7/Chapter 9/Relations.w"
bp->form_of_relation = Relation_Sym_VtoV;
bp->arbitrary = TRUE;
bp->test_function = Code__Schemas__new("(Relation_TestVtoV(*1,Rel_Record_%d,*2,true))",
bp->allocation_id);
bp->make_true_function = Code__Schemas__new("(Relation_NowVtoV(*1,Rel_Record_%d,*2,true))",
bp->allocation_id);
bp->make_false_function = Code__Schemas__new("(Relation_NowNVtoV(*1,Rel_Record_%d,*2,true))",
bp->allocation_id);
bp->record_needed = TRUE;
}
#line 202 "inform7/Chapter 9/Relations.w"
else
{
#line 615 "inform7/Chapter 9/Relations.w"
bp->form_of_relation = Relation_VtoV;
bp->arbitrary = TRUE;
bp->test_function = Code__Schemas__new("(Relation_TestVtoV(*1,Rel_Record_%d,*2,false))",
bp->allocation_id);
bp->make_true_function = Code__Schemas__new("(Relation_NowVtoV(*1,Rel_Record_%d,*2,false))",
bp->allocation_id);
bp->make_false_function = Code__Schemas__new("(Relation_NowNVtoV(*1,Rel_Record_%d,*2,false))",
bp->allocation_id);
bp->record_needed = TRUE;
}
#line 203 "inform7/Chapter 9/Relations.w"
;
}
if (dynamic) {
if (calling_made)
{
#line 549 "inform7/Chapter 9/Relations.w"
Problems__sentence_problem(_P_(C9RelNotStoredInProperty),
"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 207 "inform7/Chapter 9/Relations.w"
;
{
#line 725 "inform7/Chapter 9/Relations.w"
bp->test_function = Code__Schemas__new("(RelationTest(Rel_Record_%d,RELS_TEST,*1,*2))",
bp->allocation_id);
bp->make_true_function = Code__Schemas__new("(RelationTest(Rel_Record_%d,RELS_ASSERT_TRUE,*1,*2))",
bp->allocation_id);
bp->make_false_function = Code__Schemas__new("(RelationTest(Rel_Record_%d,RELS_ASSERT_FALSE,*1,*2))",
bp->allocation_id);
}
#line 208 "inform7/Chapter 9/Relations.w"
;
Kinds__RunTime__ensure_basic_heap_present();
} else {
if (provide_prn)
Calculus__Propositions__assert_true_about(
Calculus__Propositions__to_provide_property(prn), storage_infs, prevailing_mood);
{
#line 699 "inform7/Chapter 9/Relations.w"
if (i6_prn_name) {
i6_schema *f0 = NULL, *f1 = NULL;
if (left_unique) {
if (right_kind) {
if (Kinds__le(right_kind, K_object))
f0 = Code__Schemas__new("(*1.%s)", i6_prn_name);
else
f0 = Code__Schemas__new("(GProperty(%k, *1, %s))",
right_kind, i6_prn_name);
}
} else if (right_unique) {
if (left_kind) {
if (Kinds__le(left_kind, K_object))
f1 = Code__Schemas__new("(*1.%s)", i6_prn_name);
else
f1 = Code__Schemas__new("(GProperty(%k, *1, %s))",
left_kind, i6_prn_name);
}
}
if (f0) Semantics__BPs__Terms__set_function(&(bp->term_details[0]), f0);
if (f1) Semantics__BPs__Terms__set_function(&(bp->term_details[1]), f1);
}
}
#line 214 "inform7/Chapter 9/Relations.w"
;
}
if ((Kinds__lt(left_kind, K_object)) || (Kinds__lt(right_kind, K_object))) {
relation_guard *rg = CREATE(relation_guard);
rg->check_L = NULL; if (Kinds__lt(left_kind, K_object)) rg->check_L = left_kind;
rg->check_R = NULL; if (Kinds__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 = Semantics__BPs__Terms__get_function(&(bp->term_details[0]));
rg->f1 = Semantics__BPs__Terms__get_function(&(bp->term_details[1]));
if (rg->f0) Semantics__BPs__Terms__set_function(&(bp->term_details[0]),
Code__Schemas__new("(RGuard_f0_%d(*1))", rg->allocation_id));
if (rg->f1) Semantics__BPs__Terms__set_function(&(bp->term_details[1]),
Code__Schemas__new("(RGuard_f1_%d(*1))", rg->allocation_id));
if (bp->test_function)
bp->test_function = Code__Schemas__new("(RGuard_T_%d(*1,*2))", rg->allocation_id);
if (bp->make_true_function)
bp->make_true_function = Code__Schemas__new("(RGuard_MT_%d(*1,*2))", rg->allocation_id);
if (bp->make_false_function)
bp->make_false_function = Code__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 256 "inform7/Chapter 9/Relations.w"
int relates_sentence_left_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 259 "inform7/Chapter 9/Relations.w"
int relates_sentence_right_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 264 "inform7/Chapter 9/Relations.w"
int relation_term_right_named_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 268 "inform7/Chapter 9/Relations.w"
int relation_term_right_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 274 "inform7/Chapter 9/Relations.w"
int relation_term_basic_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 279 "inform7/Chapter 9/Relations.w"
#line 736 "inform7/Chapter 9/Relations.w"
int parse_relation_term_type(int w1, int w2, kind **set_K, char *side) {
if (parse_nt_against_word_range(k_kind_articled_NTM, w1, w2, NULL, NULL)) { *set_K = most_recent_result_p; return TRUE; }
*set_K = NULL;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_text(3, side);
Problems__handmade_problem(_P_(C9RelatedKindsUnknown));
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 755 "inform7/Chapter 9/Relations.w"
int check_finite_range(kind *K) {
if (Kinds__is_an_enumeration(K)) return TRUE;
if (K == NULL) return TRUE; /* to recover from earlier problems */
if ((Kinds__le(K, K_object)) || (Kinds__definite(K) == FALSE))
Problems__sentence_problem(_P_(C9RangeOverlyBroad),
"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 779 "inform7/Chapter 9/Relations.w"
void Semantics__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 804 "inform7/Chapter 9/Relations.w"
void compile_relation_records(OUTPUT_STREAM) {
binary_predicate *bp;
LOOP_OVER(bp, binary_predicate) {
if (bp->record_needed) {
{
#line 864 "inform7/Chapter 9/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, Semantics__BPs__kind(bp),
FALSE, 8);
WRITE("NULL NULL\n");
{
#line 884 "inform7/Chapter 9/Relations.w"
WRITE("\""); Text__Words__copy_to_stream(OUT, &(bp->relation_name)); WRITE(" relation\"\n");
}
#line 871 "inform7/Chapter 9/Relations.w"
; WRITE(" ");
{
#line 889 "inform7/Chapter 9/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+RELS_LOOKUP_ANY+RELS_LOOKUP_ALL_X+RELS_LOOKUP_ALL_Y+RELS_LIST");
switch(dbp->form_of_relation) {
case Relation_Implicit:
if (Semantics__BPs__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 872 "inform7/Chapter 9/Relations.w"
; WRITE(" ");
{
#line 914 "inform7/Chapter 9/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 873 "inform7/Chapter 9/Relations.w"
; WRITE(" ");
{
#line 941 "inform7/Chapter 9/Relations.w"
Kinds__RuntimeIDs__compile_strong(OUT, Semantics__BPs__kind(bp));
}
#line 874 "inform7/Chapter 9/Relations.w"
; WRITE(" ");
{
#line 956 "inform7/Chapter 9/Relations.w"
WRITE("Rel_Handler_%d", bp->allocation_id);
}
#line 875 "inform7/Chapter 9/Relations.w"
; WRITE(" ");
{
#line 946 "inform7/Chapter 9/Relations.w"
WRITE("\"");
if (bp->form_of_relation == Relation_Implicit)
WRITE("%s", Semantics__BPs__get_log_name(bp));
else Text__print_raw_text_to_stream(bp->bp_created_at->word_ref1,
bp->bp_created_at->word_ref2, OUT);
WRITE("\"");
}
#line 876 "inform7/Chapter 9/Relations.w"
;
WRITE(";\n");
}
OUTDENT;
}
#line 808 "inform7/Chapter 9/Relations.w"
;
if (bp->dynamic_memory == FALSE)
{
#line 961 "inform7/Chapter 9/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 = Code__Routines__begin_numbered(OUT, "Rel_Handler_%d", bp->allocation_id);
Code__LocalVariables__add_named_call("rr");
Code__LocalVariables__add_named_call("task");
Code__LocalVariables__add_named_call("X");
Code__LocalVariables__add_named_call("Y");
Code__LocalVariables__add_internal_local_c("Z1", "loop counter");
Code__LocalVariables__add_internal_local_c("Z2", "loop counter");
Code__LocalVariables__add_internal_local_c("Z3", "loop counter");
Code__LocalVariables__add_internal_local_c("Z4", "loop counter");
WRITE("switch (task) {\n"); INDENT;
annotated_i6_schema asch; i6_schema *i6s = NULL;
asch = Calculus__Atoms__blank_asch();
WRITE("RELS_TEST: if (");
i6s = Semantics__BPs__get_i6_schema(TEST_ATOM_TASK, dbp, &asch);
int j, adapted = FALSE;
for (j=0; j<2; j++) {
i6_schema *fnsc = Semantics__BPs__get_term_as_function_of_other(bp, j);
if (fnsc) {
if (j == 0) {
WRITE("X == ");
Code__Schemas__expand_textual(fnsc, OUT, Y, Y);
adapted = TRUE;
} else {
WRITE("Y == ");
Code__Schemas__expand_textual(fnsc, OUT, X, X);
adapted = TRUE;
}
}
}
if (adapted == FALSE) {
if (i6s == NULL) WRITE("false");
else Code__Schemas__expand_textual(i6s, OUT, X, Y);
}
WRITE(") rtrue; rfalse;\n");
{
#line 1063 "inform7/Chapter 9/Relations.w"
WRITE("RELS_LOOKUP_ANY: ");
WRITE("if (Y == RLANY_GET_X or RLANY_CAN_GET_X) {\n"); INDENT;
write_rels_lookup(OUT, dbp, 0);
OUTDENT; WRITE("} else {\n"); INDENT;
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;
write_rels_lookup_list(OUT, dbp, 0);
OUTDENT; WRITE("} else {\n"); INDENT;
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;
write_rels_lookup_list_all(OUT, dbp, 0);
OUTDENT; WRITE("} else if (Y == RLIST_ALL_Y) {\n"); INDENT;
write_rels_lookup_list_all(OUT, dbp, 1);
OUTDENT; WRITE("}\n");
WRITE("return X;\n");
}
#line 1000 "inform7/Chapter 9/Relations.w"
;
if (Semantics__BPs__can_be_made_true_at_runtime(bp)) {
asch = Calculus__Atoms__blank_asch();
WRITE("RELS_ASSERT_TRUE: ");
i6s = Semantics__BPs__get_i6_schema(NOW_ATOM_TRUE_TASK, dbp, &asch);
if (i6s == NULL) WRITE("rfalse");
else Code__Schemas__expand_textual(i6s, OUT, X, Y);
WRITE("; rtrue;\n");
asch = Calculus__Atoms__blank_asch();
WRITE("RELS_ASSERT_FALSE: ");
i6s = Semantics__BPs__get_i6_schema(NOW_ATOM_FALSE_TASK, dbp, &asch);
if (i6s == NULL) WRITE("rfalse");
else Code__Schemas__expand_textual(i6s, OUT, X, Y);
WRITE("; rtrue;\n");
}
{
#line 1046 "inform7/Chapter 9/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 1015 "inform7/Chapter 9/Relations.w"
;
{
#line 1025 "inform7/Chapter 9/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 1016 "inform7/Chapter 9/Relations.w"
;
OUTDENT; WRITE("}\n");
WRITE("rfalse;\n");
OUT = Code__Routines__end(OUT);
}
#line 810 "inform7/Chapter 9/Relations.w"
;
}
}
OUT = Code__Routines__begin(OUT, "CreateDynamicRelations");
Code__LocalVariables__add_internal_local_c("i", "loop counter");
Code__LocalVariables__add_internal_local_c("rel", "new relation");
LOOP_OVER(bp, binary_predicate) {
if ((bp->dynamic_memory) && (bp->right_way_round)) {
WRITE("BlkValueCreate(");
Kinds__RuntimeIDs__compile_strong(OUT, Semantics__BPs__kind(bp));
WRITE(", Rel_Record_%d);\n", bp->allocation_id);
WRITE("RELATION_TY_Name(Rel_Record_%d, \"", bp->allocation_id);
Text__Words__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 = Code__Routines__end(OUT);
}
#line 1089 "inform7/Chapter 9/Relations.w"
void write_rels_lookup(OUTPUT_STREAM, binary_predicate *bp, int t) {
kind *K = Semantics__BPs__term_kind(bp, t);
if ((bp == R_containment) && (K == NULL)) K = K_object;
if (Kinds__compile_domain_possible(K)) {
i6_schema loop_schema;
if (Kinds__write_loop_schema(&loop_schema, K, FALSE)) {
Code__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");
WRITE("return DefaultValueOfKOV(");
Kinds__RuntimeIDs__compile_strong(OUT, K);
WRITE(");\n");
}
#line 1116 "inform7/Chapter 9/Relations.w"
void write_rels_lookup_list(OUTPUT_STREAM, binary_predicate *bp, int t) {
kind *K = Semantics__BPs__term_kind(bp, t);
if ((bp == R_containment) && (K == NULL)) K = K_object;
if (Kinds__compile_domain_possible(K)) {
i6_schema loop_schema;
if (Kinds__write_loop_schema(&loop_schema, K, FALSE)) {
Code__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 1138 "inform7/Chapter 9/Relations.w"
void write_rels_lookup_list_all(OUTPUT_STREAM, binary_predicate *bp, int t) {
kind *KL = Semantics__BPs__term_kind(bp, 0);
kind *KR = Semantics__BPs__term_kind(bp, 1);
if ((bp == R_containment) && (KL == NULL)) KL = K_object;
if ((bp == R_containment) && (KR == NULL)) KR = K_object;
if ((Kinds__compile_domain_possible(KL)) && (Kinds__compile_domain_possible(KL))) {
i6_schema loop_schema_L, loop_schema_R;
if ((Kinds__write_loop_schema(&loop_schema_L, KL, FALSE)) &&
(Kinds__write_loop_schema(&loop_schema_R, KR, FALSE))) {
Code__Schemas__expand_textual(&loop_schema_L, OUT, "Z1", "Z2");
WRITE(" {\n"); INDENT;
Code__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 1166 "inform7/Chapter 9/Relations.w"
void Semantics__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__RuntimeIDs__compile_strong(OUT, K);
WRITE(" EmptyRelationHandler ");
WRITE("\"default value of "); Kinds__Textual__write(OUT, K); WRITE("\"");
WRITE(";\n"); OUTDENT;
}
void Semantics__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__RuntimeIDs__compile_strong(OUT, K);
char *handler = "DoubleHashSetRelationHandler";
kind *EK = Kinds__unary_construction_material(K);
if (Kinds__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 1202 "inform7/Chapter 9/Relations.w"
void Semantics__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 1228 "inform7/Chapter 9/Relations.w"
int word_compiled = 0, bit_counter = 0, words_compiled;
void begin_bit_stream(OUTPUT_STREAM) {
word_compiled = 0; bit_counter = 0; words_compiled = 0;
}
void 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 end_bit_stream(OUTPUT_STREAM) {
while (bit_counter != 0) compile_bit(OUT, 0);
}
#line 1255 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__compile_vtov_storage(OUTPUT_STREAM, binary_predicate *bp) {
int left_count = 0, right_count = 0, words_used = 0, bytes_used = 0;
allocate_index_storage();
{
#line 1296 "inform7/Chapter 9/Relations.w"
left_count = relation_range(bp, 0);
right_count = relation_range(bp, 1);
if (right_count >= MAX_RIGHT_DOMAIN_SIZE) internal_error("Far too many relatees");
}
#line 1258 "inform7/Chapter 9/Relations.w"
;
WRITE("Array V2V_Bitmap_%d --> ", bp->allocation_id);
{
#line 1303 "inform7/Chapter 9/Relations.w"
kind *left_kind = Semantics__BPs__term_kind(bp, 0);
kind *right_kind = Semantics__BPs__term_kind(bp, 1);
if ((Kinds__lt(left_kind, K_object)) && (left_count > 0))
WRITE("IK%d_Count ", Kinds__I6_classnumber(left_kind));
else WRITE("0 ");
if ((Kinds__lt(right_kind, K_object)) && (right_count > 0))
WRITE("IK%d_Count ", Kinds__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__get_name_of_printing_rule(left_kind));
WRITE(" %s ! To print right instances\n",
Kinds__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 1260 "inform7/Chapter 9/Relations.w"
;
if ((left_count > 0) && (right_count > 0))
{
#line 1384 "inform7/Chapter 9/Relations.w"
char row_flags[MAX_RIGHT_DOMAIN_SIZE];
begin_bit_stream(OUT);
inference_subject *infs;
LOOP_OVER(infs, inference_subject)
if (infs_in_domain(infs, bp, 0)) {
int j;
for (j=0; j<right_count; j++) row_flags[j] = 0;
{
#line 1402 "inform7/Chapter 9/Relations.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Semantics__BPs__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[get_relation_index(right_infs, 1)] = 1;
}
}
#line 1392 "inform7/Chapter 9/Relations.w"
;
for (j=0; j<right_count; j++) compile_bit(OUT, row_flags[j]);
}
end_bit_stream(OUT);
words_used += words_compiled;
}
#line 1263 "inform7/Chapter 9/Relations.w"
;
WRITE(";\n");
if ((left_count > 0) && (right_count > 0))
{
#line 1336 "inform7/Chapter 9/Relations.w"
kind *left_kind = Semantics__BPs__term_kind(bp, 0);
kind *right_kind = Semantics__BPs__term_kind(bp, 1);
if ((bp->fast_route_finding) &&
(Kinds__eq(left_kind, right_kind)) &&
(Kinds__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 1268 "inform7/Chapter 9/Relations.w"
;
char rname[MAX_WORDS_IN_ASSEMBLAGE*MAX_WORD_LENGTH];
Text__Words__copy_to_string(&(bp->relation_name), rname);
Code__VirtualMachines__note_usage("relation",
bp->bp_created_at->word_ref1, bp->bp_created_at->word_ref1,
rname, words_used, bytes_used, FALSE);
free_index_storage();
}
#line 1362 "inform7/Chapter 9/Relations.w"
int infs_in_domain(inference_subject *infs, binary_predicate *bp, int index) {
if (World__Subjects__domain(infs) != NULL) return FALSE;
kind *K = Semantics__BPs__term_kind(bp, index);
if (K == NULL) return FALSE;
inference_subject *domain_infs = Kinds__as_subject(K);
if (World__Subjects__is_strictly_within(infs, domain_infs)) return TRUE;
return FALSE;
}
#line 1413 "inform7/Chapter 9/Relations.w"
int relation_range(binary_predicate *bp, int index) {
int t = 0;
inference_subject *infs;
LOOP_OVER(infs, inference_subject) {
if (infs_in_domain(infs, bp, index)) set_relation_index(infs, index, t++);
else set_relation_index(infs, index, -1);
}
return t;
}
#line 1426 "inform7/Chapter 9/Relations.w"
int *relation_indices = NULL;
void allocate_index_storage(void) {
int nc = NUMBER_CREATED(inference_subject);
relation_indices = (int *) (Memory__I7_calloc(nc, 2*sizeof(int), OBJECT_COMPILATION_MREASON));
}
void 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 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 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 1511 "inform7/Chapter 9/Relations.w"
void Semantics__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 1551 "inform7/Chapter 9/Relations.w"
void Semantics__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 1575 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__equivalence_relation_add_properties(binary_predicate *bp) {
kind *k = Semantics__BPs__term_kind(bp, 1);
if (Kinds__le(k, K_object)) {
instance *I;
LOOP_OVER_INSTANCES(I, k) {
inference_subject *infs = Data__Instances__as_subject(I);
{
#line 1595 "inform7/Chapter 9/Relations.w"
specification *val = Specifications__Values__new_integer_literal(
equivalence_relation_get_class(bp, infs->allocation_id));
Properties__Valued__assert(bp->i6_storage_property, infs, val, CERTAIN_CE);
}
#line 1581 "inform7/Chapter 9/Relations.w"
;
}
} else {
instance *nc;
LOOP_OVER_INSTANCES(nc, k) {
inference_subject *infs = Data__Instances__as_subject(nc);
{
#line 1595 "inform7/Chapter 9/Relations.w"
specification *val = Specifications__Values__new_integer_literal(
equivalence_relation_get_class(bp, infs->allocation_id));
Properties__Valued__assert(bp->i6_storage_property, infs, val, CERTAIN_CE);
}
#line 1587 "inform7/Chapter 9/Relations.w"
;
}
}
}
#line 1602 "inform7/Chapter 9/Relations.w"
int 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 1621 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__check_1to1_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 = Semantics__BPs__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)) {
specification *val = World__Inferences__get_property_value(inf);
inference_subject *infs2 = World__Subjects__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__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__infs_contradiction_problem(_P_(C9Relation1to1Right),
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);
}
#line 1686 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__compile_defined_relations(OUTPUT_STREAM) {
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", Semantics__BPs__get_log_name(bp));
Code__Frames__condition_routine(OUT, rname,
bp->condition_defn_w1, bp->condition_defn_w2,
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", Semantics__BPs__get_log_name(rg->guarding));
OUT = Code__Routines__begin_numbered(OUT, "RGuard_f0_%d", rg->allocation_id);
Code__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__I6_classname(rg->check_R));
WRITE("return ");
Code__Schemas__expand_textual(rg->f0, OUT, "X", "");
WRITE(";\n");
if (rg->check_R) WRITE("return nothing;\n");
} else {
WRITE("return nothing;\n");
}
OUT = Code__Routines__end(OUT);
OUT = Code__Routines__begin_numbered(OUT, "RGuard_f1_%d", rg->allocation_id);
Code__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__I6_classname(rg->check_L));
WRITE("return ");
Code__Schemas__expand_textual(rg->f1, OUT, "X", "");
WRITE(";\n");
if (rg->check_L) WRITE("return nothing;\n");
} else {
WRITE("return nothing;\n");
}
OUT = Code__Routines__end(OUT);
OUT = Code__Routines__begin_numbered(OUT, "RGuard_T_%d", rg->allocation_id);
Code__LocalVariables__add_internal_local_c("L", "left member of pair");
Code__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__I6_classname(rg->check_L));
if (rg->check_R) WRITE("(R ofclass %s) && ", Kinds__I6_classname(rg->check_R));
WRITE("(");
Code__Schemas__expand_textual(rg->inner_test, OUT, "L", "R");
WRITE(")) rtrue;\n");
}
WRITE("rfalse;\n");
OUT = Code__Routines__end(OUT);
OUT = Code__Routines__begin_numbered(OUT, "RGuard_MT_%d", rg->allocation_id);
Code__LocalVariables__add_internal_local_c("L", "left member of pair");
Code__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__I6_classname(rg->check_L));
if ((rg->check_L) && (rg->check_R)) WRITE(" && ");
if (rg->check_R) WRITE("(R ofclass %s)", Kinds__I6_classname(rg->check_R));
WRITE(") {\n"); INDENT;
Code__Schemas__expand_textual(rg->inner_make_true, OUT, "L", "R");
WRITE("; return;\n");
OUTDENT; WRITE("}\n");
WRITE("RunTimeProblem(RTP_RELKINDVIOLATION, L, R, Rel_Record_%d);\n",
rg->guarding->allocation_id);
}
OUT = Code__Routines__end(OUT);
OUT = Code__Routines__begin_numbered(OUT, "RGuard_MF_%d", rg->allocation_id);
Code__LocalVariables__add_internal_local_c("L", "left member of pair");
Code__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__I6_classname(rg->check_L));
if ((rg->check_L) && (rg->check_R)) WRITE(" && ");
if (rg->check_R) WRITE("(R ofclass %s)", Kinds__I6_classname(rg->check_R));
WRITE(") {\n"); INDENT;
Code__Schemas__expand_textual(rg->inner_make_false, OUT, "L", "R");
WRITE("; return;\n");
OUTDENT; WRITE("}\n");
WRITE("RunTimeProblem(RTP_RELKINDVIOLATION, L, R, Rel_Record_%d);\n",
rg->guarding->allocation_id);
}
OUT = Code__Routines__end(OUT);
}
}
#line 1783 "inform7/Chapter 9/Relations.w"
void Code__Frames__condition_routine(OUTPUT_STREAM, char *rname,
int w1, int w2, bp_term_details par1, bp_term_details par2) {
OUT = Code__Routines__begin(OUT, rname);
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
Semantics__BPs__Terms__add_as_call_parameter(OUT, phsf, par1);
Semantics__BPs__Terms__add_as_call_parameter(OUT, phsf, par2);
Code__LocalVariables__enable_possessive_form_of_it();
specification *spec = NULL;
if (parse_nt_against_word_range(spec_condition_NTM, w1, w2, NULL, NULL)) spec = most_recent_result_p;
if ((spec == NULL) || (Plugins__Actions__Patterns__validate_when(spec) == FALSE)) {
Problems__sentence_problem(_P_(C9BadRelationCondition),
"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__compile(OUT, spec); WRITE(";\n");
}
OUT = Code__Routines__end(OUT);
}
#line 1812 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__index_table(void) {
binary_predicate *bp;
INDEX("<p>");
Formats__HTML__begin_plain_html_table(ifl);
Formats__HTML__first_html_column(ifl, 0); INDEX("<i>name</i>");
Formats__HTML__next_html_column(ifl, 0); INDEX("<i>category</i>");
Formats__HTML__next_html_column(ifl, 0); INDEX("<i>relates this...</i>");
Formats__HTML__next_html_column(ifl, 0); INDEX("<i>...to this</i>");
Formats__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) || (Text__Words__nonempty(bp->relation_name) == FALSE)) continue;
Formats__HTML__first_html_column(ifl, 0);
Text__Words__index(&(bp->relation_name));
if (bp->bp_created_at) Index__link(bp->bp_created_at->word_ref1);
Formats__HTML__next_html_column(ifl, 0);
if (type) INDEX("%s", type); else INDEX("--");
Formats__HTML__next_html_column(ifl, 0);
Semantics__BPs__Terms__details_index(&(bp->term_details[0]));
Formats__HTML__next_html_column(ifl, 0);
Semantics__BPs__Terms__details_index(&(bp->term_details[1]));
Formats__HTML__end_html_row(ifl);
}
Formats__HTML__end_html_table(ifl);
INDEX("</p>");
}
#line 1862 "inform7/Chapter 9/Relations.w"
void Semantics__Relations__index_for_verbs(binary_predicate *bp) {
INDEX(" ... <i>");
if (bp->right_way_round == FALSE) {
bp = bp->reversal;
INDEX("reversed ");
}
Text__Words__index(&(bp->relation_name));
INDEX("</i>");
}
#line 14 "inform7/Chapter 9/Explicit Relations.w"
void Semantics__Relations__Explicit__create_initial_stock(void) {
}
void Semantics__Relations__Explicit__create_second_stock(void) {
}
#line 22 "inform7/Chapter 9/Explicit Relations.w"
int Semantics__Relations__Explicit__typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
return DECLINE_TO_MATCH;
}
#line 32 "inform7/Chapter 9/Explicit Relations.w"
int Semantics__Relations__Explicit__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
{
#line 61 "inform7/Chapter 9/Explicit Relations.w"
if (Semantics__BPs__can_be_made_true_at_runtime(bp) == FALSE) {
Problems__sentence_problem(_P_(C9Unassertable2),
"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 9/Explicit Relations.w"
;
if (Semantics__BPs__store_dynamically(bp)) {
World__Inferences__draw_relation_spec(bp, spec0, spec1);
return TRUE;
} else {
if ((infs0 == NULL) || (infs1 == NULL))
{
#line 74 "inform7/Chapter 9/Explicit Relations.w"
Problems__sentence_problem(_P_(C9CantRelateNothing),
"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 9/Explicit Relations.w"
;
if (Semantics__BPs__allow_arbitrary_assertions(bp)) {
World__Inferences__draw_relation(bp, infs0, infs1);
if ((Semantics__BPs__get_form_of_relation(bp) == Relation_Sym_VtoV) && (infs0 != infs1))
World__Inferences__draw_relation(bp, infs1, infs0);
return TRUE;
}
if (Semantics__BPs__is_explicit_with_runtime_storage(bp)) {
infer_property_based_relation(bp, infs1, infs0);
if ((Semantics__BPs__get_form_of_relation(bp) == Relation_Sym_OtoO) && (infs0 != infs1))
infer_property_based_relation(bp, infs0, infs1);
return TRUE;
}
}
return FALSE;
}
#line 91 "inform7/Chapter 9/Explicit Relations.w"
void infer_property_based_relation(binary_predicate *relation,
inference_subject *infs0, inference_subject *infs1) {
if (Semantics__BPs__get_form_of_relation(relation) == Relation_VtoO) {
inference_subject *swap=infs0; infs0=infs1; infs1=swap;
}
property *prn = Semantics__BPs__get_i6_storage_property(relation);
World__Inferences__draw_property(infs0, prn, World__Subjects__as_constant(infs1));
}
#line 103 "inform7/Chapter 9/Explicit Relations.w"
int Semantics__Relations__Explicit__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) {
return FALSE;
}
#line 110 "inform7/Chapter 9/Explicit Relations.w"
int Semantics__Relations__Explicit__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 20 "inform7/Chapter 9/The Universal Relation.w"
void Semantics__Relations__Universal__create_initial_stock(void) {
R_universal =
Semantics__BPs__make_pair(UNIVERSAL_KBP,
Semantics__BPs__Terms__new(NULL), Semantics__BPs__Terms__new(NULL),
"provides", NULL, NULL, NULL, NULL,
Text__Languages__wording(relation_names_NTM, UNIVERSAL_RELATION_NAME));
R_meaning =
Semantics__BPs__make_pair(UNIVERSAL_KBP,
Semantics__BPs__Terms__new(NULL), Semantics__BPs__Terms__new(NULL),
"means", NULL, NULL, NULL, NULL,
Text__Languages__wording(relation_names_NTM, MEANING_RELATION_NAME));
}
#line 37 "inform7/Chapter 9/The Universal Relation.w"
void Semantics__Relations__Universal__create_second_stock(void) {
}
#line 44 "inform7/Chapter 9/The Universal Relation.w"
int Semantics__Relations__Universal__typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
if (bp == R_meaning) {
if (Kinds__eq(kinds_of_terms[0], K_verb) == FALSE) {
Problems__quote_kind(4, kinds_of_terms[0]);
Problems__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__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__tcp_problem(_P_(C9BadUniversal1), 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__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__compatible(cleft, rleft) == NEVER_MATCH) {
Problems__quote_kind(5, kinds_of_terms[0]);
Problems__quote_kind(4, cleft);
Problems__tcp_problem(_P_(C9UniversalMisappliedLeft), 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__compatible(cright, rright) == NEVER_MATCH) {
Problems__quote_kind(5, kinds_of_terms[0]);
Problems__quote_kind(4, cright);
Problems__tcp_problem(_P_(C9UniversalMisappliedRight), 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 9/The Universal Relation.w"
int Semantics__Relations__Universal__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
return FALSE;
}
#line 120 "inform7/Chapter 9/The Universal Relation.w"
int Semantics__Relations__Universal__compile(int task, binary_predicate *bp,
annotated_i6_schema *asch) {
if (bp == R_meaning) {
switch(task) {
case TEST_ATOM_TASK:
Code__Schemas__modify(asch->schema, "*=-(BlkValueCompare(*1(CV_MEANING), *2)==0)");
return TRUE;
}
} else {
switch(task) {
case TEST_ATOM_TASK:
Code__Schemas__modify(asch->schema, "*=-((RlnGetF(*1, RR_HANDLER))(*1, RELS_TEST, *&))");
return TRUE;
case NOW_ATOM_TRUE_TASK:
Code__Schemas__modify(asch->schema, "*=-((RlnGetF(*1, RR_HANDLER))(*1, RELS_ASSERT_TRUE, *&))");
return TRUE;
case NOW_ATOM_FALSE_TASK:
Code__Schemas__modify(asch->schema, "*=-((RlnGetF(*1, RR_HANDLER))(*1, RELS_ASSERT_FALSE, *&))");
return TRUE;
}
}
return FALSE;
}
#line 148 "inform7/Chapter 9/The Universal Relation.w"
int Semantics__Relations__Universal__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 83 "inform7/Chapter 9/Conjugation of Verbs.w"
parse_node *set_where_created = NULL;
verb_usage *register_vu(word_assemblage wa, int negated, int tensed,
binary_predicate *root, verb_conjugation *vc, int unexpected_upper_casing_used) {
if (Text__Words__nonempty(wa) == FALSE) return NULL;
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;
Text__Languages__mark_as_verb(Text__Words__first_word(&wa));
return vu;
}
#line 103 "inform7/Chapter 9/Conjugation of Verbs.w"
int 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 116 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_usage *find_vu(word_assemblage against) {
verb_usage *vu;
LOOP_OVER(vu, verb_usage)
if (Text__Words__compare(&(vu->vu_text), &against))
return vu;
return NULL;
}
#line 127 "inform7/Chapter 9/Conjugation of Verbs.w"
binary_predicate *Semantics__VerbUsage__get_meaning(verb_usage *vu) {
return vu->vu_meaning;
}
int Semantics__VerbUsage__get_tense_used(verb_usage *vu) {
return vu->tensed;
}
int Semantics__VerbUsage__is_used_negatively(verb_usage *vu) {
return vu->negated_form_of_verb;
}
#line 143 "inform7/Chapter 9/Conjugation of Verbs.w"
int same_prop_as_registered = FALSE;
preposition_usage *Semantics__PrepositionUsage__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;
Text__Languages__mark_as_preposition(Text__Words__first_word(&wa));
vocabulary_entry **array; int length;
Text__Words__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(
Text__Languages__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 174 "inform7/Chapter 9/Conjugation of Verbs.w"
preposition_usage *find_pu(word_assemblage against) {
preposition_usage *pu;
LOOP_OVER(pu, preposition_usage)
if (Text__Words__compare(&(pu->pu_text), &against))
return pu;
return NULL;
}
#line 185 "inform7/Chapter 9/Conjugation of Verbs.w"
int Semantics__PrepositionUsage__implicitly_negates(preposition_usage *pu) {
if (pu == NULL) return FALSE;
return pu->negated_sense;
}
binary_predicate *Semantics__PrepositionUsage__get_meaning(preposition_usage *pu) {
if (pu == NULL) return NULL;
return pu->pu_meaning;
}
#line 205 "inform7/Chapter 9/Conjugation of Verbs.w"
int parse_against_verb(int w1, int w2, verb_usage *vu) {
if ((vu->vu_allow_unexpected_upper_case == FALSE) &&
(Text__unexpectedly_upper_case(w1))) return -1;
return Text__Words__parse_as_strictly_initial_text(w1, w2, &(vu->vu_text));
}
#line 234 "inform7/Chapter 9/Conjugation of Verbs.w"
int general_verb_NTMR(int w1, int w2, int *X, void **XP) {
#line 235 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_usage *vu;
LOOP_OVER(vu, verb_usage) {
int i = parse_against_verb(w1, w2, vu);
if ((i>w1) && (i<=w2)) {
*XP = vu;
return i-1;
}
}
return FALSE;
}
#line 251 "inform7/Chapter 9/Conjugation of Verbs.w"
int general_verb_present_positive_NTMR(int w1, int w2, int *X, void **XP) {
#line 252 "inform7/Chapter 9/Conjugation of Verbs.w"
/* if (Text__unexpectedly_upper_case(w1)) return FALSE; */
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER(vu, verb_usage) {
if ((vu->tensed == IS_TENSE) &&
(vu->negated_form_of_verb == FALSE) &&
(vu_foreign(vu) == FALSE)) {
int i = parse_against_verb(w1, w2, vu);
if ((i>w1) && (i<=w2)) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 273 "inform7/Chapter 9/Conjugation of Verbs.w"
int foreign_verb_present_positive_NTMR(int w1, int w2, int *X, void **XP) {
#line 274 "inform7/Chapter 9/Conjugation of Verbs.w"
/* if (Text__unexpectedly_upper_case(w1)) return FALSE; */
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER(vu, verb_usage) {
if ((vu->tensed == IS_TENSE) &&
(vu->negated_form_of_verb == FALSE) &&
(vu_foreign(vu))) {
int i = parse_against_verb(w1, w2, vu);
if ((i>w1) && (i<=w2)) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 297 "inform7/Chapter 9/Conjugation of Verbs.w"
int copular_verb_NTMR(int w1, int w2, int *X, void **XP) {
#line 298 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER(vu, verb_usage) {
if (vu->vu_meaning == R_equality) {
int i = parse_against_verb(w1, w2, vu);
if ((i>w1) && (i<=w2)) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 317 "inform7/Chapter 9/Conjugation of Verbs.w"
int copular_verb_present_positive_NTMR(int w1, int w2, int *X, void **XP) {
#line 318 "inform7/Chapter 9/Conjugation of Verbs.w"
/* if (Text__unexpectedly_upper_case(w1)) return FALSE; */
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER(vu, verb_usage) {
if ((vu->tensed == IS_TENSE) &&
(vu->vu_meaning == R_equality) &&
(vu->negated_form_of_verb == FALSE) &&
(vu_foreign(vu) == FALSE)) {
int i = parse_against_verb(w1, w2, vu);
if ((i>w1) && (i<=w2)) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 342 "inform7/Chapter 9/Conjugation of Verbs.w"
int negated_noncopular_verb_present_NTMR(int w1, int w2, int *X, void **XP) {
#line 343 "inform7/Chapter 9/Conjugation of Verbs.w"
/* if (Text__unexpectedly_upper_case(w1)) return FALSE; */
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER(vu, verb_usage) {
if ((vu->tensed == IS_TENSE) &&
(vu->vu_meaning != R_equality) &&
(vu->negated_form_of_verb == TRUE)) {
int i = parse_against_verb(w1, w2, vu);
if ((i>w1) && (i<=w2)) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 365 "inform7/Chapter 9/Conjugation of Verbs.w"
int universal_verb_NTMR(int w1, int w2, int *X, void **XP) {
#line 366 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_usage *vu;
LOOP_OVER(vu, verb_usage)
if (vu->vu_meaning == R_universal) {
int i = parse_against_verb(w1, w2, vu);
if ((i>w1) && (i<=w2)) {
*XP = vu;
return i-1;
}
}
return FALSE;
}
#line 384 "inform7/Chapter 9/Conjugation of Verbs.w"
int possession_verb_present_positive_NTMR(int w1, int w2, int *X, void **XP) {
#line 385 "inform7/Chapter 9/Conjugation of Verbs.w"
/* if (Text__unexpectedly_upper_case(w1)) return FALSE; */
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER(vu, verb_usage) {
if ((vu->tensed == IS_TENSE) &&
(vu->vu_meaning == a_has_b_predicate) &&
(vu->negated_form_of_verb == FALSE) &&
(vu_foreign(vu) == FALSE)) {
int i = parse_against_verb(w1, w2, vu);
if ((i>w1) && (i<=w2)) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 407 "inform7/Chapter 9/Conjugation of Verbs.w"
int negated_verb_NTMR(int w1, int w2, int *X, void **XP) {
#line 408 "inform7/Chapter 9/Conjugation of Verbs.w"
/* if (Text__unexpectedly_upper_case(w1)) return FALSE; */
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER(vu, verb_usage) {
if (vu->negated_form_of_verb == TRUE) {
int i = parse_against_verb(w1, w2, vu);
if ((i>w1) && (i<=w2)) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 427 "inform7/Chapter 9/Conjugation of Verbs.w"
int past_tense_verb_NTMR(int w1, int w2, int *X, void **XP) {
#line 428 "inform7/Chapter 9/Conjugation of Verbs.w"
/* if (Text__unexpectedly_upper_case(w1)) return FALSE; */
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER(vu, verb_usage) {
if (vu->tensed != IS_TENSE) {
int i = parse_against_verb(w1, w2, vu);
if ((i>w1) && (i<=w2)) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 455 "inform7/Chapter 9/Conjugation of Verbs.w"
int parse_prep_against(int w1, int w2, preposition_usage *pu, int fill) {
int str1 = -1, str2 = -1;
if (pu->is_same_property_as) {
str1 = pu->is_same_property_as->word_ref1;
str2 = pu->is_same_property_as->word_ref2;
}
return Text__Words__parse_as_weakly_initial_text(w1, w2, &(pu->pu_text), str1, str2,
pu->allow_unexpected_upper_case, TRUE);
}
#line 468 "inform7/Chapter 9/Conjugation of Verbs.w"
int preposition_NTMR(int w1, int w2, int *X, void **XP) {
#line 469 "inform7/Chapter 9/Conjugation of Verbs.w"
if (Text__Vocabulary__test_flags(w1, PREPOSITION_MC) == FALSE) return FALSE;
preposition_usage *pu;
LOOP_OVER(pu, preposition_usage) {
int i = parse_prep_against(w1, w2, pu, TRUE);
if ((i>w1) && (i<=w2+1)) {
*XP = pu;
return i-1;
}
}
return FALSE;
}
#line 489 "inform7/Chapter 9/Conjugation of Verbs.w"
int preposition_implying_player_NTMR(int w1, int w2, int *X, void **XP) {
#line 490 "inform7/Chapter 9/Conjugation of Verbs.w"
if (Text__Vocabulary__test_flags(w1, PREPOSITION_MC) == FALSE) return FALSE;
preposition_usage *pu;
LOOP_OVER(pu, preposition_usage)
if (pu->player_implied) {
int i = parse_prep_against(w1, w2, pu, TRUE);
if ((i>w1) && (i<=w2)) {
*XP = pu;
return i-1;
}
}
return FALSE;
}
#line 508 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__VerbUsage__log(verb_usage *vu) {
LOG("VU: $w ", &(vu->vu_text));
if (vu->negated_form_of_verb) LOG("(negated) ");
Code__Chronology__log_tense_number(vu->tensed);
LOG(" -> %s", Semantics__BPs__get_log_name(vu->vu_meaning));
}
void Semantics__PrepositionUsage__log(preposition_usage *pu) {
LOG("PU: $w ", &(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", Semantics__BPs__get_log_name(pu->pu_meaning));
}
void Semantics__VerbUsage__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) {
Semantics__VerbUsage__log(vu);
LOG("\n");
}
LOOP_OVER(pu, preposition_usage) {
Semantics__PrepositionUsage__log(pu);
LOG("\n");
}
}
#line 540 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__VerbUsage__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) && (Semantics__VerbUsage__is_used_negatively(vu) == FALSE)
&& (Semantics__VerbUsage__get_tense_used(vu) == tense)) {
vocabulary_entry *lastword = Text__Words__last_word(&(vu->vu_text));
if (f) {
Formats__HTML__open_para(ifl, 2, "tight");
INDEX("<i>%s:</i>&nbsp;", tensename);
} else INDEX("; ");
if (strcmp(Text__Vocabulary__get_exemplar(lastword, FALSE), "by") == 0)
INDEX("B ");
else INDEX("A ");
Text__Words__index(&(vu->vu_text));
if (strcmp(Text__Vocabulary__get_exemplar(lastword, FALSE), "by") == 0)
INDEX("A");
else INDEX("B");
f = FALSE;
}
if (f == FALSE) INDEX("</p>\n");
}
void Semantics__VerbUsage__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(vu->where_vu_created->word_ref1);
Semantics__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(pu->where_pu_created->word_ref1);
Semantics__Relations__index_for_verbs(pu->pu_meaning);
return;
}
}
#line 594 "inform7/Chapter 9/Conjugation of Verbs.w"
int inequality_conjugations_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 599 "inform7/Chapter 9/Conjugation of Verbs.w"
#line 603 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__VerbUsage__stock(void) {
set_where_created = NULL;
current_main_verb = NULL;
register_vu(Text__Languages__wording(inequality_conjugations_NTM, 0),
FALSE, IS_TENSE, R_numerically_less_than, NULL, FALSE);
register_vu(Text__Languages__wording(inequality_conjugations_NTM, 1),
FALSE, IS_TENSE, R_numerically_greater_than, NULL, FALSE);
register_vu(Text__Languages__wording(inequality_conjugations_NTM, 2),
FALSE, IS_TENSE, R_numerically_less_than_or_equal_to, NULL, FALSE);
register_vu(Text__Languages__wording(inequality_conjugations_NTM, 3),
FALSE, IS_TENSE, R_numerically_greater_than_or_equal_to, NULL, FALSE);
}
#line 632 "inform7/Chapter 9/Conjugation of Verbs.w"
void 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);
register_main_forms_of_verb(vc, &(vc->active_tabulation), root,
unexpected_upper_casing_used);
if (root != R_equality) {
binary_predicate *bpr = Semantics__BPs__get_reversal(root);
register_main_forms_of_verb(vc, &(vc->passive_tabulation), bpr,
unexpected_upper_casing_used);
if (Text__Words__nonempty(vc->present_participle))
Semantics__PrepositionUsage__register(vc->present_participle,
FALSE, root, FALSE, unexpected_upper_casing_used);
}
}
void register_main_forms_of_verb(verb_conjugation *vc, verb_tabulation *vt,
binary_predicate *root, int unexpected_upper_casing_used) {
if (Text__Words__nonempty(vt->to_be_auxiliary)) {
Semantics__PrepositionUsage__register(vt->to_be_auxiliary,
FALSE, root, FALSE, unexpected_upper_casing_used);
return;
}
verb_usage *vu;
vu = register_vu(vt->vc_text[HASBEEN_TENSE][1][THIRD_PERSON_SINGULAR],
TRUE, HASBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = register_vu(vt->vc_text[HASBEEN_TENSE][1][THIRD_PERSON_PLURAL],
TRUE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = register_vu(vt->vc_text[HADBEEN_TENSE][1][THIRD_PERSON_SINGULAR],
TRUE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = register_vu(vt->vc_text[HADBEEN_TENSE][1][THIRD_PERSON_PLURAL],
TRUE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = register_vu(vt->vc_text[HASBEEN_TENSE][0][THIRD_PERSON_SINGULAR],
FALSE, HASBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = register_vu(vt->vc_text[HASBEEN_TENSE][0][THIRD_PERSON_PLURAL],
FALSE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = register_vu(vt->vc_text[HADBEEN_TENSE][0][THIRD_PERSON_SINGULAR],
FALSE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = register_vu(vt->vc_text[HADBEEN_TENSE][0][THIRD_PERSON_PLURAL],
FALSE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = 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 = 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 = register_vu(vt->vc_text[WAS_TENSE][1][THIRD_PERSON_SINGULAR],
TRUE, WAS_TENSE, root, vc, unexpected_upper_casing_used);
vu = register_vu(vt->vc_text[WAS_TENSE][1][THIRD_PERSON_PLURAL],
TRUE, WAS_TENSE, root, vc, unexpected_upper_casing_used);
vu = 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 = register_vu(vt->vc_text[IS_TENSE][0][THIRD_PERSON_PLURAL],
FALSE, IS_TENSE, root, vc, unexpected_upper_casing_used);
vu = register_vu(vt->vc_text[WAS_TENSE][0][THIRD_PERSON_SINGULAR],
FALSE, WAS_TENSE, root, vc, unexpected_upper_casing_used);
vu = register_vu(vt->vc_text[WAS_TENSE][0][THIRD_PERSON_PLURAL],
FALSE, WAS_TENSE, root, vc, unexpected_upper_casing_used);
}
#line 706 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__PrepositionUsage__register_comparative(int wn, binary_predicate *root) {
set_where_created = current_sentence;
Semantics__PrepositionUsage__register(
Text__Languages__merge(comparative_property_construction_NTM, 0,
Text__Words__lit_1(Text__word(wn))),
FALSE, root, FALSE, FALSE);
}
void Semantics__PrepositionUsage__register_same_property_as(binary_predicate *root) {
set_where_created = current_sentence;
preposition_usage *pu =
Semantics__PrepositionUsage__register(
Text__Languages__merge(same_property_as_construction_NTM, 0,
Text__Words__lit_1(PARBREAK_V)),
FALSE, root, TRUE, FALSE);
pu->is_same_property_as = Properties__Valued__Relations__bp_get_same_as_property(root);
}
#line 731 "inform7/Chapter 9/Conjugation of Verbs.w"
int comparative_property_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 733 "inform7/Chapter 9/Conjugation of Verbs.w"
#line 737 "inform7/Chapter 9/Conjugation of Verbs.w"
int same_property_as_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 739 "inform7/Chapter 9/Conjugation of Verbs.w"
#line 745 "inform7/Chapter 9/Conjugation of Verbs.w"
int same_property_as_in_lexicon_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 747 "inform7/Chapter 9/Conjugation of Verbs.w"
#line 772 "inform7/Chapter 9/Conjugation of Verbs.w"
int verb_implies_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 775 "inform7/Chapter 9/Conjugation of Verbs.w"
int infinitive_usage_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 779 "inform7/Chapter 9/Conjugation of Verbs.w"
int infinitive_usage_exceptional_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 784 "inform7/Chapter 9/Conjugation of Verbs.w"
#line 789 "inform7/Chapter 9/Conjugation of Verbs.w"
int conjugation_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 792 "inform7/Chapter 9/Conjugation of Verbs.w"
#line 802 "inform7/Chapter 9/Conjugation of Verbs.w"
int participle_like_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 805 "inform7/Chapter 9/Conjugation of Verbs.w"
#line 818 "inform7/Chapter 9/Conjugation of Verbs.w"
int verb_implies_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 873 "inform7/Chapter 9/Conjugation of Verbs.w"
*X = REL_VERBM;
*XP = Semantics__PrepositionUsage__get_meaning(RP[1]);
}
#line 821 "inform7/Chapter 9/Conjugation of Verbs.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 860 "inform7/Chapter 9/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__sentence_problem(_P_(BelievedImpossible),
"that's another verb which has no meaning at present",
"so this doesn't help me.");
}
}
#line 822 "inform7/Chapter 9/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 831 "inform7/Chapter 9/Conjugation of Verbs.w"
*X = NONE_VERBM;
Problems__sentence_problem(_P_(C9VerbRelationUnknown),
"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 824 "inform7/Chapter 9/Conjugation of Verbs.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 841 "inform7/Chapter 9/Conjugation of Verbs.w"
*X = NONE_VERBM;
Problems__sentence_problem(_P_(C9VerbRelationVague),
"that's too vague",
"calling a relation simply 'relation'.");
}
#line 825 "inform7/Chapter 9/Conjugation of Verbs.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7:
{
#line 850 "inform7/Chapter 9/Conjugation of Verbs.w"
*X = NONE_VERBM;
Problems__sentence_problem(_P_(C9VerbUnknownMeaning),
"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 826 "inform7/Chapter 9/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 827 "inform7/Chapter 9/Conjugation of Verbs.w"
#line 879 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__VerbUsage__parse_new(parse_node *PN) {
int w1, w2, rw1 = -1, rw2 = -1, parts1 = -1, parts2 = -1;
natural_language *nl = Parser__Nodes__get_defn_language(PN->down);
binary_predicate *bp = NULL;
int conjugate_automatically = FALSE;
set_where_created = current_sentence;
if (PN->down->next->next) {
rw1 = PN->down->next->next->word_ref1; rw2 = PN->down->next->next->word_ref2;
{
#line 921 "inform7/Chapter 9/Conjugation of Verbs.w"
int reversal_flag = FALSE;
parse_nt_against_word_range(verb_implies_sentence_object_NTM, rw1, rw2, NULL, NULL);
switch (most_recent_result) {
case PROP_VERBM:
GET_RW(verb_implies_sentence_object_NTM, 1, rw1, rw2);
bp = Properties__Valued__Relations__make_set_property_BP(rw1, rw2); 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 = Semantics__BPs__get_reversal(bp);
}
#line 889 "inform7/Chapter 9/Conjugation of Verbs.w"
;
}
w1 = PN->down->next->word_ref1; w2 = PN->down->next->word_ref2;
if (parse_nt_against_word_range(verb_implies_sentence_subject_NTM, w1, w2, NULL, NULL)) {
int r = most_recent_result;
if (r == DEFAULT_VERBU) {
r = REGULAR_VERBU;
GET_RW(infinitive_usage_NTM, 1, w1, w2);
} else {
GET_RW(infinitive_usage_exceptional_NTM, 1, w1, w2);
}
if (giving_parts_NTMV) GET_RW(verb_implies_sentence_subject_NTM, 1, parts1, parts2);
int unexpected_upper_casing_used = FALSE;
{
#line 1117 "inform7/Chapter 9/Conjugation of Verbs.w"
int i;
for (i=w1; i<=w2; i++)
if (Text__unexpectedly_upper_case(i))
unexpected_upper_casing_used = TRUE;
}
#line 904 "inform7/Chapter 9/Conjugation of Verbs.w"
;
switch (r) {
case PREP_VERBU:
{
#line 1063 "inform7/Chapter 9/Conjugation of Verbs.w"
word_assemblage wa = Text__Words__lit_0();
{
#line 1084 "inform7/Chapter 9/Conjugation of Verbs.w"
if (parts1 >= 0) {
Problems__sentence_problem(_P_(C9PrepositionConjugated),
"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 1064 "inform7/Chapter 9/Conjugation of Verbs.w"
;
{
#line 1095 "inform7/Chapter 9/Conjugation of Verbs.w"
if (w2 >= w1+MAX_WORDS_IN_PREPOSITION) {
Problems__sentence_problem(_P_(C9PrepositionLong),
"prepositions can be very long indeed in today's Inform",
"but not as long as this.");
return;
}
wa = Text__Words__from_range(w1, w2);
}
#line 1065 "inform7/Chapter 9/Conjugation of Verbs.w"
;
{
#line 1125 "inform7/Chapter 9/Conjugation of Verbs.w"
preposition_usage *duplicate_pu = NULL;
duplicate_pu = find_pu(wa);
if (duplicate_pu) {
if (duplicate_pu->where_pu_created)
Problems__two_sentences_problem(_P_(C9DuplicateVerbs3),
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__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 1066 "inform7/Chapter 9/Conjugation of Verbs.w"
;
{
#line 1145 "inform7/Chapter 9/Conjugation of Verbs.w"
Semantics__PrepositionUsage__register(wa, FALSE, bp, FALSE, unexpected_upper_casing_used);
}
#line 1067 "inform7/Chapter 9/Conjugation of Verbs.w"
;
}
#line 907 "inform7/Chapter 9/Conjugation of Verbs.w"
;
break;
case REGULAR_VERBU:
{
#line 936 "inform7/Chapter 9/Conjugation of Verbs.w"
word_assemblage infinitive = Text__Words__from_range(w1, w2);
word_assemblage present_singular = Text__Words__lit_0();
word_assemblage present_plural = Text__Words__lit_0();
word_assemblage past = Text__Words__lit_0();
word_assemblage past_participle = Text__Words__lit_0();
word_assemblage participle = Text__Words__lit_0();
if (parts1 < 0) conjugate_automatically = TRUE;
else
{
#line 957 "inform7/Chapter 9/Conjugation of Verbs.w"
int more_to_read = TRUE;
int participle_count = 0;
while (more_to_read) {
int c1, c2;
if (parse_nt_against_word_range(list_comma_division_NTM, parts1, parts2, NULL, NULL)) {
GET_RW(list_comma_division_NTM, 1, c1, c2);
GET_RW(list_comma_division_NTM, 2, parts1, parts2);
more_to_read = TRUE;
} else {
c1 = parts1; c2 = parts2;
more_to_read = FALSE;
}
{
#line 977 "inform7/Chapter 9/Conjugation of Verbs.w"
if ((parse_nt_against_word_range(conjugation_NTM, c1, c2, NULL, NULL)) == FALSE)
{
#line 1012 "inform7/Chapter 9/Conjugation of Verbs.w"
Problems__sentence_problem(_P_(C9VerbMalformed),
"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 978 "inform7/Chapter 9/Conjugation of Verbs.w"
;
GET_RW(conjugation_NTM, 1, c1, c2);
int number = most_recent_result;
int is_a_participle = is_participle_NTMV;
if (c2-c1+1 > MAX_WORDS_IN_VERB)
{
#line 1012 "inform7/Chapter 9/Conjugation of Verbs.w"
Problems__sentence_problem(_P_(C9VerbMalformed),
"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 983 "inform7/Chapter 9/Conjugation of Verbs.w"
;
if (is_a_participle) {
participle_count++;
if ((parse_nt_against_word_range(participle_like_NTM, c1, c2, NULL, NULL)) ||
(Text__Words__nonempty(past_participle)))
participle = Text__Words__from_range(c1, c2);
else
past_participle = Text__Words__from_range(c1, c2);
} else {
if (number == 2) {
if (Text__Words__nonempty(present_plural)) {
Problems__sentence_problem(_P_(C9PresentPluralTwice),
"the present plural has been given twice",
"since two of the principal parts of this verb begin "
"with 'they'.");
}
present_plural = Text__Words__from_range(c1, c2);
} else {
if (Text__Words__nonempty(present_singular))
past = Text__Words__from_range(c1, c2);
else
present_singular = Text__Words__from_range(c1, c2);
}
}
}
#line 969 "inform7/Chapter 9/Conjugation of Verbs.w"
;
}
if (Text__Words__nonempty(present_plural) == FALSE) present_plural = infinitive;
}
#line 944 "inform7/Chapter 9/Conjugation of Verbs.w"
;
{
#line 1025 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_usage *duplicate_vu = find_vu(present_singular);
if (duplicate_vu) {
if (duplicate_vu->where_vu_created)
Problems__two_sentences_problem(_P_(C9DuplicateVerbs1),
duplicate_vu->where_vu_created,
"this gives us two definitions of what appears to be the same verb",
"or at least has the same infinitive form.");
else
Problems__sentence_problem(_P_(C9DuplicateVerbs2),
"this verb definition appears to clash with a built-in verb",
"a table of which can be seen on the Phrasebook index.");
return;
}
}
#line 945 "inform7/Chapter 9/Conjugation of Verbs.w"
;
{
#line 1042 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_conjugation *vc = Semantics__find_vc_by_infinitive(infinitive);
if (vc == NULL) {
word_assemblage overrides[7];
int no_overrides = 7;
overrides[BASE_FORM_TYPE] = Text__Words__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] = Text__Words__lit_0();
overrides[5] = present_singular;
overrides[6] = past;
vc = Text__Languages__conjugate_verb(infinitive, overrides, no_overrides, nl);
}
if ((vc) && (bp)) register_regular_verb(vc, bp, unexpected_upper_casing_used);
}
#line 946 "inform7/Chapter 9/Conjugation of Verbs.w"
;
}
#line 910 "inform7/Chapter 9/Conjugation of Verbs.w"
;
break;
case NONE_VERBU:
return;
}
}
}
#line 1150 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__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 1175 "inform7/Chapter 9/Conjugation of Verbs.w"
void Semantics__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 1193 "inform7/Chapter 9/Conjugation of Verbs.w"
char i6_routine_name[32];
sprintf(i6_routine_name, "ConjugateVerb_%d", vc->allocation_id);
OUT = Code__Routines__begin(OUT, i6_routine_name);
Code__LocalVariables__add_named_call("fn");
Code__LocalVariables__add_named_call("vp");
Code__LocalVariables__add_named_call("t");
Code__LocalVariables__add_named_call("modal_to");
WRITE("switch (fn) {\n"); INDENT;
WRITE("1: "); conj_from_wa(OUT, &(vc->infinitive), vc, 0);
WRITE("\n2: "); conj_from_wa(OUT, &(vc->past_participle), vc, 0);
WRITE("\n3: "); conj_from_wa(OUT, &(vc->present_participle), vc, 0);
WRITE("\n");
int modal_verb = FALSE;
{
#line 1230 "inform7/Chapter 9/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 1207 "inform7/Chapter 9/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);
Semantics__BPs__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 1239 "inform7/Chapter 9/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 (Text__Words__nonempty(*wa)) {
if (some_exist) {
if (Text__Words__compare(wa, common) == FALSE)
some_differ = TRUE;
if (part != 3) {
if (common_except_3PS == NULL) common_except_3PS = wa;
else if (Text__Words__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 1282 "inform7/Chapter 9/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 (Text__Words__nonempty(*wa)) {
WRITE("%d: ", part);
int mau = vc->active_tabulation.modal_auxiliary_usage[tense][sense][part-1];
conj_from_wa(OUT, wa, vc, mau);
WRITE("\n");
}
}
OUTDENT; WRITE("}\n");
}
#line 1269 "inform7/Chapter 9/Conjugation of Verbs.w"
else
{
#line 1297 "inform7/Chapter 9/Conjugation of Verbs.w"
word_assemblage *wa = &(vc->active_tabulation.vc_text[tense][sense][2]);
WRITE("if (vp == 3) { "); conj_from_wa(OUT, wa, vc, 0);
wa = &(vc->active_tabulation.vc_text[tense][sense][0]);
WRITE(" } else { "); conj_from_wa(OUT, wa, vc, 0);
WRITE(" }\n");
}
#line 1271 "inform7/Chapter 9/Conjugation of Verbs.w"
;
} else {
{
#line 1306 "inform7/Chapter 9/Conjugation of Verbs.w"
word_assemblage *wa = &(vc->active_tabulation.vc_text[tense][sense][0]);
conj_from_wa(OUT, wa, vc, 0);
WRITE("\n");
}
#line 1273 "inform7/Chapter 9/Conjugation of Verbs.w"
;
}
}
}
OUTDENT; WRITE("}\n");
}
#line 1220 "inform7/Chapter 9/Conjugation of Verbs.w"
;
OUTDENT;
}
OUTDENT; WRITE("}\n");
OUT = Code__Routines__end(OUT);
}
#line 1182 "inform7/Chapter 9/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 1313 "inform7/Chapter 9/Conjugation of Verbs.w"
void conj_from_wa(OUTPUT_STREAM, word_assemblage *wa, verb_conjugation *vc, int mau) {
WRITE("print \"");
if ((takes_contraction_form(wa) == FALSE) && (takes_contraction_form(&(vc->infinitive))))
WRITE(" ");
int i, n;
vocabulary_entry **words;
Text__Words__as_array(wa, &words, &n);
for (i=0; i<n; i++) {
if (i>0) WRITE(" ");
char *q = Text__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;
int w1 = lexer_wordcount;
Text__feed_into_lexer(" ", FALSE, NULL);
Text__feed_into_lexer(unstarred, FALSE, NULL);
Text__feed_into_lexer(" ", FALSE, NULL);
int w2 = lexer_wordcount - 1;
adjectival_phrase *aph = Semantics__Adjectives__Meanings__declare_textually(w1, w2);
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 takes_contraction_form(word_assemblage *wa) {
vocabulary_entry *ve = Text__Words__first_word(wa);
if (ve == NULL) return FALSE;
char *p = Text__Vocabulary__get_exemplar(ve, FALSE);
if (p[0] == '\'') return TRUE;
return FALSE;
}
verb_conjugation *Semantics__find_vc_by_infinitive(word_assemblage infinitive) {
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if (Text__Words__compare(&infinitive, &(vc->infinitive)))
return vc;
return NULL;
}
#line 1362 "inform7/Chapter 9/Conjugation of Verbs.w"
int adaptive_verb_NTMR(int w1, int w2, int *X, void **XP) {
#line 1363 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if (vc->auxiliary_only == FALSE) {
int p = Text__Languages__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 (Text__Words__compare_with_range(we_form, w1, w2)) {
*XP = vc; *X = FALSE; return TRUE;
}
if (Text__Words__compare_with_range(we_dont_form, w1, w2)) {
*XP = vc; *X = TRUE; return TRUE;
}
}
return FALSE;
}
int auxiliary_verb_only_NTMR(int w1, int w2, int *X, void **XP) {
#line 1380 "inform7/Chapter 9/Conjugation of Verbs.w"
return FALSE;
}
int instance_of_verb_NTMR(int w1, int w2, int *X, void **XP) {
#line 1384 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if ((vc->auxiliary_only == FALSE) && (vc->instance_of_verb)) {
int p = Text__Languages__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 (Text__Words__compare_with_range(we_form, w1, w2)) {
*XP = vc; *X = FALSE; return TRUE;
}
if (Text__Words__compare_with_range(we_dont_form, w1, w2)) {
*XP = vc; *X = TRUE; return TRUE;
}
}
return FALSE;
}
int not_instance_of_verb_at_run_time_NTMR(int w1, int w2, int *X, void **XP) {
#line 1401 "inform7/Chapter 9/Conjugation of Verbs.w"
return FALSE;
}
int modal_verb_NTMR(int w1, int w2, int *X, void **XP) {
#line 1405 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if (vc->auxiliary_only == FALSE) {
int p = Text__Languages__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 (Text__Words__compare_with_range(we_form, w1, w2)) {
*XP = vc; *X = FALSE; return TRUE;
}
if (Text__Words__compare_with_range(we_dont_form, w1, w2)) {
*XP = vc; *X = TRUE; return TRUE;
}
}
}
return FALSE;
}
int verb_infinitive_NTMR(int w1, int w2, int *X, void **XP) {
#line 1424 "inform7/Chapter 9/Conjugation of Verbs.w"
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if (vc->auxiliary_only == FALSE) {
if (Text__Words__compare_with_range(&(vc->infinitive), w1, w2)) {
*XP = vc; *X = FALSE; return TRUE;
}
}
return FALSE;
}
#line 165 "inform7/Chapter 9/Adjectives.w"
int adjective_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 166 "inform7/Chapter 9/Adjectives.w"
meaning_list *ml = Parser__SP__parse_excerpt(ADJECTIVE_MC, w1, w2);
if (ml) {
*XP = RETRIEVE_POINTER_adjectival_phrase(
Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
return TRUE;
}
return FALSE;
}
#line 181 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase *Semantics__Adjectives__Phrases__parse(int w1, int w2) {
if (parse_nt_against_word_range(adjective_name_NTM, w1, w2, NULL, NULL)) return most_recent_result_p;
return NULL;
}
#line 190 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase *aph_from_word_range(int w1, int w2, natural_language *nl) {
adjectival_phrase *aph = NULL;
if (w1 >= 0) aph = Semantics__Adjectives__Phrases__parse(w1, w2);
if (aph) return aph;
aph = CREATE(adjectival_phrase);
aph->adjective_names = Text__Clusters__new();
Text__Clusters__add_with_agreements(aph->adjective_names, w1, w2, nl);
aph->possible_meanings = NULL; aph->sorted_meanings = NULL;
if ((nl == NULL) && (w1 >= 0)) {
if (parse_nt_against_word_range(article_NTM, w1, w2, NULL, NULL)) {
Problems__sentence_problem(_P_(C9ArticleAsAdjective),
"a defined adjective cannot consist only of an article such as "
"'a' or 'the'",
"since this will lead to parsing ambiguities.");
} else {
Semantics__Nouns__ExcerptMeanings__register(ADJECTIVE_MC, 0,
w1, w2, STORE_POINTER_adjectival_phrase(aph));
int n;
for (n = w1; n <= w2; n++)
Text__Languages__mark_word(n, s_adjective_NTM);
}
}
LOGIF(VARIABLE_CREATIONS, "Created adjectival phrase: $a\n", aph);
return aph;
}
#line 219 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__get_text(adjectival_phrase *aph, int *w1, int *w2, int plural) {
Text__Clusters__get_name(aph->adjective_names, w1, w2, plural);
}
#line 226 "inform7/Chapter 9/Adjectives.w"
sentence_handler NEW_ADJ_SH_handler =
{ SENTENCE_NT, NEW_ADJ_VB, 1, declare_meaningless_adj };
#line 232 "inform7/Chapter 9/Adjectives.w"
void declare_meaningless_adj(parse_node *p) {
parse_node *adjname = p->down->next;
parse_node *meaning = adjname->next;
int w1 = adjname->word_ref1, w2 = adjname->word_ref2;
int m1 = -1, m2 = -1;
if (meaning) { m1 = meaning->word_ref1; m2 = meaning->word_ref2; }
if (parse_nt_against_word_range(adaptive_adjective_NTM, w1, w2, NULL, NULL)) return;
Semantics__Adjectives__Meanings__declare_textually(w1, w2);
}
adjectival_phrase *Semantics__Adjectives__Meanings__declare_textually(int w1, int w2) {
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
int c1, c2;
Text__Clusters__get_name_in_play(aph->adjective_names, &c1, &c2, FALSE);
if (Text__compare_word_range(c1, c2, w1, w2)) return aph;
}
return aph_from_word_range(w1, w2, language_of_play);
}
void Semantics__Adjectives__Meanings__test_adjective(OUTPUT_STREAM, int w1, int w2) {
adjectival_phrase *aph = Semantics__Adjectives__Meanings__declare_textually(w1, w2);
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: ");
int c1, c2;
Text__Clusters__get_name_general(aph->adjective_names, &c1, &c2,
language_of_play, n, g);
Text__print_text_to_stream(c1, c2, OUT);
}
WRITE("^");
}
}
#line 279 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase *Semantics__Adjectives__Meanings__declare(adjective_meaning *am,
int w1, int w2) {
adjectival_phrase *aph = aph_from_word_range(w1, w2, 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 298 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase *Semantics__Adjectives__Meanings__get_aph(adjective_meaning *am) {
return am->owning_adjective;
}
#line 307 "inform7/Chapter 9/Adjectives.w"
void aph_sortrandom_meanings(adjectival_phrase *aph) {
if (aph == NULL) internal_error("tried to sort meanings for null APH");
aph->sorted_meanings = am_list_sort(aph->possible_meanings);
}
adjective_meaning *am_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)
am_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 (compare_ams(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 350 "inform7/Chapter 9/Adjectives.w"
adjective_meaning *aph_get_sorted_definition_list(adjectival_phrase *aph) {
return aph->sorted_meanings;
}
#line 357 "inform7/Chapter 9/Adjectives.w"
adjective_meaning *Semantics__Adjectives__first_meaning(adjectival_phrase *aph) {
return aph->possible_meanings;
}
#line 365 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__log(adjectival_phrase *aph) {
if (aph == NULL) { LOG("<null adjectival phrase>"); return; }
int w1, w2;
Semantics__Adjectives__Meanings__get_text(aph, &w1, &w2, FALSE);
if (logging_to_I6_text) LOG("'$W'", w1, w2);
else LOG("A%d'$W'", aph->allocation_id, w1, w2);
}
#line 376 "inform7/Chapter 9/Adjectives.w"
void aph_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->index_w1, am->index_w2,
am->domain_infs, am->domain_kind);
}
#line 399 "inform7/Chapter 9/Adjectives.w"
adjective_meaning *Semantics__Adjectives__Meanings__new(int form,
general_pointer details, int ix1, int ix2) {
int i;
adjective_meaning *am = CREATE(adjective_meaning);
am->defined_at = current_sentence;
am->index_w1 = ix1; am->index_w2 = ix2;
am->owning_adjective = NULL;
am->next_meaning = NULL;
am->next_sorted = NULL;
am->definition_domain_w1 = -1; am->definition_domain_w2 = -1;
am->domain_infs = NULL; am->domain_kind = NULL;
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 (i=1; i<=NO_ADJECTIVE_TASKS; i++) {
am->task_via_support_routine[i] = NOT_APPLICABLE;
Code__Schemas__modify(&(am->i6s_for_runtime_task[i]), "");
Code__Schemas__modify(&(am->i6s_to_transfer_to_SR[i]), "");
}
am->am_negated_from = NULL;
return am;
}
#line 434 "inform7/Chapter 9/Adjectives.w"
adjective_meaning *Semantics__Adjectives__Meanings__negate(adjective_meaning *am) {
int i;
adjective_meaning *neg = CREATE(adjective_meaning);
neg->defined_at = current_sentence;
neg->index_w1 = am->index_w1; neg->index_w2 = am->index_w2;
neg->owning_adjective = NULL;
neg->next_meaning = NULL;
neg->next_sorted = NULL;
neg->definition_domain_w1 = am->definition_domain_w1;
neg->definition_domain_w2 = am->definition_domain_w2;
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 (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];
Code__Schemas__modify(&(neg->i6s_to_transfer_to_SR[j]), "");
}
neg->am_negated_from = am;
return neg;
}
int Semantics__Adjectives__Meanings__get_form(adjective_meaning *am) {
if (am == NULL) return -1;
return am->adjective_form;
}
#line 491 "inform7/Chapter 9/Adjectives.w"
int domain_weak_match(kind *K1, kind *K2) {
if (Kinds__RuntimeIDs__weak(K1) == Kinds__RuntimeIDs__weak(K2))
return TRUE;
return FALSE;
}
#line 501 "inform7/Chapter 9/Adjectives.w"
int domain_subj_compare(inference_subject *infs, adjective_meaning *am) {
instance *I = World__Subjects__as_instance(infs);
if (I == NULL) return TRUE;
if (am->domain_infs == Kinds__as_subject(K_object)) return TRUE;
while (infs) {
if (am->domain_infs == infs) return TRUE;
infs = World__Subjects__narrowest_broader_subject(infs);
}
return FALSE;
}
#line 530 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__set_domain_from_word_range(adjective_meaning *am,
int w1, int w2) {
am->domain_infs = NULL; am->domain_kind = NULL;
am->definition_domain_w1 = w1; am->definition_domain_w2 = w2;
am_set_definition_domain(am, TRUE);
}
void Semantics__Adjectives__Meanings__set_domain_from_instance(adjective_meaning *am,
instance *I) {
if (I == NULL) {
am->domain_infs = Kinds__as_subject(K_object);
am->domain_kind = K_object;
} else {
am->domain_infs = Data__Instances__as_subject(I);
am->domain_kind = Kinds__weaken(Data__Instances__kind(I));
}
am->definition_domain_w1 = -1; am->definition_domain_w2 = -1;
}
#line 554 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__set_domain_from_kind(adjective_meaning *am, kind *K) {
if ((K == NULL) || (Kinds__le(K, K_object))) K = K_object;
am->domain_infs = Kinds__as_subject(K);
am->domain_kind = K;
am->definition_domain_w1 = -1; am->definition_domain_w2 = -1;
}
#line 564 "inform7/Chapter 9/Adjectives.w"
kind *Semantics__Adjectives__Meanings__get_domain(adjective_meaning *am) {
if (am->domain_infs == NULL) return NULL;
return am->domain_kind;
}
kind *Semantics__Adjectives__Meanings__get_domain_forcing(adjective_meaning *am) {
am_set_definition_domain(am, TRUE);
if (am->domain_infs == NULL) return NULL;
return am->domain_kind;
}
#line 581 "inform7/Chapter 9/Adjectives.w"
void am_set_definition_domain(adjective_meaning *am, int early) {
if (am->domain_infs) return;
if (am->definition_domain_w1 < 0) internal_error("undeclared domain kind for AM");
specification *supplied = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, am->definition_domain_w1, am->definition_domain_w2, NULL, NULL))
supplied = most_recent_result_p;
if (supplied == NULL)
{
#line 605 "inform7/Chapter 9/Adjectives.w"
if ((early) || (am->problems_thrown++ > 0)) return;
current_sentence = am->defined_at;
Problems__adjective_problem(_P_(C9AdjDomainUnknown),
am->index_w1, am->index_w2, am->definition_domain_w1, am->definition_domain_w2,
"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 587 "inform7/Chapter 9/Adjectives.w"
;
{
#line 616 "inform7/Chapter 9/Adjectives.w"
if ((Specifications__Values__is_actual_CONSTANT(supplied)) &&
(Specifications__describes_an_object_vaguely_or_exactly(supplied) == FALSE) &&
(Specifications__Values__get_named_constant_if_any(supplied) == NULL)) {
if ((early) || (am->problems_thrown++ > 0)) return;
current_sentence = am->defined_at;
Problems__adjective_problem(_P_(C9AdjDomainSurreal),
am->index_w1, am->index_w2, am->definition_domain_w1, am->definition_domain_w2,
"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 588 "inform7/Chapter 9/Adjectives.w"
;
kind *K = NULL;
if (Specifications__family_is(supplied, CONDITION_FMY)) {
if (Specifications__Conditions__get_described_kind(supplied))
K = Specifications__Conditions__get_described_kind(supplied);
else K = K_object;
{
#line 635 "inform7/Chapter 9/Adjectives.w"
if (Specifications__Conditions__is_qualified_DESCRIPTION(supplied)) {
if (am->problems_thrown++ > 0) return;
current_sentence = am->defined_at;
Problems__adjective_problem(_P_(C9AdjDomainSlippery),
am->index_w1, am->index_w2, am->definition_domain_w1, am->definition_domain_w2,
"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 594 "inform7/Chapter 9/Adjectives.w"
;
} else if (Specifications__family_is(supplied, VALUE_FMY))
K = Specifications__Values__kind_when_VALUE_is_evaluated(supplied);
if (K == NULL)
{
#line 605 "inform7/Chapter 9/Adjectives.w"
if ((early) || (am->problems_thrown++ > 0)) return;
current_sentence = am->defined_at;
Problems__adjective_problem(_P_(C9AdjDomainUnknown),
am->index_w1, am->index_w2, am->definition_domain_w1, am->definition_domain_w2,
"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 597 "inform7/Chapter 9/Adjectives.w"
;
{
#line 654 "inform7/Chapter 9/Adjectives.w"
instance *I = Specifications__Values__instance_of_CONSTANT_object_if_any(supplied);
if (I) supplied = Data__Instances__get_value(I);
else if (Kinds__lt(K, K_object))
supplied = Specifications__Values__new_generic_CONSTANT(K);
am->domain_infs = World__Subjects__from_specification(supplied);
am->domain_kind = K;
}
#line 598 "inform7/Chapter 9/Adjectives.w"
;
}
#line 683 "inform7/Chapter 9/Adjectives.w"
int compare_ams(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 (World__Subjects__is_strictly_within(am1->domain_infs, am2->domain_infs)) return 1;
if (World__Subjects__is_strictly_within(am2->domain_infs, am1->domain_infs)) return -1;
kind *K1 = World__Subjects__as_nonobject_kind(am1->domain_infs);
kind *K2 = World__Subjects__as_nonobject_kind(am2->domain_infs);
if ((K1) && (K2)) {
int c1, c2;
c1 = Kinds__compatible(K1, K2); c2 = Kinds__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 713 "inform7/Chapter 9/Adjectives.w"
if ((am1->defined_at->word_ref1 >= 0) &&
(am2->defined_at->word_ref1 >= 0) &&
(am1->adjective_form != ENUMERATIVE_KADJ) &&
(am2->adjective_form != ENUMERATIVE_KADJ)) {
extension_file *ef1 =
Text__Reader__sf_get_extension_corresponding(
Text__file_of_origin(am1->defined_at->word_ref1));
extension_file *ef2 =
Text__Reader__sf_get_extension_corresponding(
Text__file_of_origin(am2->defined_at->word_ref1));
if ((ef1 == ef2) || ((ef1) && (ef2))) {
current_sentence = am1->defined_at;
Problems__quote_words_as_source(1, am1->index_w1, am1->index_w2);
Problems__quote_words_as_source(2, am2->index_w1, am2->index_w2);
Problems__handmade_problem(_P_(C9AdjDomainDuplicated));
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 700 "inform7/Chapter 9/Adjectives.w"
;
return am2->allocation_id - am1->allocation_id;
}
#line 770 "inform7/Chapter 9/Adjectives.w"
int Semantics__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) am_set_definition_domain(am, TRUE);
kind *am_kind = Semantics__Adjectives__Meanings__get_domain(am);
if (Kinds__le(am_kind, K_object)) {
if (K == NULL) return TRUE;
if (Kinds__le(K, K_object)) return TRUE;
} else {
if ((K) && (Kinds__le(K, K_object) == FALSE) &&
(Kinds__compatible(K, am_kind) == ALWAYS_MATCH))
return TRUE;
}
}
}
return FALSE;
}
#line 795 "inform7/Chapter 9/Adjectives.w"
instance *Semantics__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 *Semantics__Adjectives__Phrases__has_EORP_meaning(adjectival_phrase *aph) {
adjective_meaning *am;
for (am = aph->possible_meanings; am; am = am->next_meaning)
if (am->adjective_form == EORP_KADJ)
return RETRIEVE_POINTER_property(am->detailed_meaning);
return NULL;
}
#line 841 "inform7/Chapter 9/Adjectives.w"
int Semantics__Adjectives__Phrases__assert(adjectival_phrase *aph, kind *kind_domain,
inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) {
adjective_meaning *am;
aph_sortrandom_meanings(aph);
for (am = aph->sorted_meanings; am; am = am->next_sorted) {
if (domain_weak_match(kind_domain,
Semantics__Adjectives__Meanings__get_domain(am)) == FALSE) continue;
if (domain_subj_compare(infs_to_assert_on, am) == FALSE) continue;
if (am_assert(am, infs_to_assert_on, val_to_assert_on, parity)) return TRUE;
}
return FALSE;
}
#line 903 "inform7/Chapter 9/Adjectives.w"
i6_schema *Semantics__Adjectives__Meanings__set_i6_schema(adjective_meaning *am,
int T, int via_support) {
kind *K = Semantics__Adjectives__Meanings__get_domain(am);
if (K == NULL) K = K_object;
if (Kinds__le(K, K_object)) via_support = TRUE;
am->task_via_support_routine[T] = via_support;
return &(am->i6s_for_runtime_task[T]);
}
#line 923 "inform7/Chapter 9/Adjectives.w"
i6_schema *Semantics__Adjectives__Phrases__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 = am_list_sort(aph->possible_meanings);
for (am = aph->sorted_meanings; am; am = am->next_sorted) {
kind *am_kind = Semantics__Adjectives__Meanings__get_domain(am);
if (am_kind == NULL) am_set_definition_domain(am, FALSE);
if (domain_weak_match(kind_domain, am_kind) == FALSE) continue;
am_compiling_soon(am, T);
switch (am->task_via_support_routine[T]) {
case FALSE: return &(am->i6s_for_runtime_task[T]);
case TRUE:
if (Code__Schemas__empty(&(am->i6s_to_transfer_to_SR[T])))
{
#line 949 "inform7/Chapter 9/Adjectives.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;
}
}
Code__Schemas__modify(&(am->i6s_to_transfer_to_SR[T]), "*=-(%sAdj_%d_t%d_v%d(*1))",
negation_operator, adj_number, task, Kinds__RuntimeIDs__weak(am_kind));
}
#line 937 "inform7/Chapter 9/Adjectives.w"
;
return &(am->i6s_to_transfer_to_SR[T]);
}
}
return NULL;
}
#line 968 "inform7/Chapter 9/Adjectives.w"
int Semantics__Adjectives__Phrases__write_adjective_test_routine(OUTPUT_STREAM,
adjectival_phrase *aph) {
i6_schema *sch;
int weak_id = Kinds__RuntimeIDs__weak(K_object);
sch = Semantics__Adjectives__Phrases__get_i6_schema(aph, NULL,
TEST_ADJECTIVE_TASK);
if (sch == NULL) {
if (aph->possible_meanings == NULL) return FALSE;
kind *am_kind =
Semantics__Adjectives__Meanings__get_domain(aph->possible_meanings);
if (am_kind == NULL) return FALSE;
weak_id = Kinds__RuntimeIDs__weak(am_kind);
}
WRITE("Adj_%d_t%d_v%d", aph->allocation_id, TEST_ADJECTIVE_TASK, weak_id);
return TRUE;
}
#line 989 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__pass_task_to_support_routine(adjective_meaning *am,
int T) {
Semantics__Adjectives__Meanings__set_i6_schema(am, T, TRUE);
}
#line 998 "inform7/Chapter 9/Adjectives.w"
int Semantics__Adjectives__Meanings__get_ready_flag(adjective_meaning *am) {
return am->am_ready_flag;
}
void Semantics__Adjectives__Meanings__set_ready_flag(adjective_meaning *am) {
am->am_ready_flag = TRUE;
}
#line 1012 "inform7/Chapter 9/Adjectives.w"
adjective_meaning *am_list_next_domain_kind(adjective_meaning *am, kind **K, int T) {
while ((am) && ((am->defined_already) || (am_compile(am, T, NULL, NULL) == FALSE)))
am = am->next_sorted;
if (am == NULL) return NULL;
*K = Semantics__Adjectives__Meanings__get_domain(am);
return am->next_sorted;
}
#line 1028 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Phrases__compile_support_code(OUTPUT_STREAM) {
{
#line 1052 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
adjective_meaning *am;
for (am = aph->possible_meanings; am; am = am->next_meaning) {
am_set_definition_domain(am, FALSE);
am->defined_already = FALSE;
}
aph->sorted_meanings = am_list_sort(aph->possible_meanings);
}
}
#line 1029 "inform7/Chapter 9/Adjectives.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 = am_list_next_domain_kind(am, &K, T);
if (K)
{
#line 1065 "inform7/Chapter 9/Adjectives.w"
int w1, w2;
Semantics__Adjectives__Meanings__get_text(aph, &w1, &w2, FALSE);
LOGIF(VARIABLE_CREATIONS, "Compiling support code for $W applying to $u, task %d\n",
w1, w2, K, T);
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "Adj_%d_t%d_v%d", aph->allocation_id, T,
Kinds__RuntimeIDs__weak(K));
OUT = Code__Routines__begin(OUT, i6_routine_identifier);
{
#line 1114 "inform7/Chapter 9/Adjectives.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) &&
(domain_weak_match(K, Semantics__Adjectives__Meanings__get_domain(am))))
add_K = K;
Code__LocalVariables__Pronoun__add(Code__Frames__current_stack_frame(), -1, -1, add_K);
Code__LocalVariables__enable_possessive_form_of_it();
}
#line 1075 "inform7/Chapter 9/Adjectives.w"
;
WRITE("! meaning of \"");
if (w1 >= 0) Text__print_raw_text_within_i6_literal(OUT, w1, w2);
else WRITE("<nameless>");
WRITE("\"\n");
if (problem_count == 0)
am_list_compile(aph->sorted_meanings, OUT, Code__Frames__current_stack_frame(), K, T);
WRITE("rfalse;\n");
OUT = Code__Routines__end(OUT);
}
#line 1041 "inform7/Chapter 9/Adjectives.w"
;
}
}
}
}
#line 1130 "inform7/Chapter 9/Adjectives.w"
void am_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 ((am_compile(am, T, NULL, NULL)) &&
(domain_weak_match(K, Semantics__Adjectives__Meanings__get_domain(am)))) {
current_sentence = am->defined_at;
char cond[1024]; cond[0] = 0;
World__Subjects__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("(~~(");
am_compile(am, T, OUT, phsf);
if ((am->meaning_parity == FALSE) && (T == TEST_ADJECTIVE_TASK)) WRITE("))");
WRITE(";\n");
am->defined_already = TRUE;
}
}
#line 1176 "inform7/Chapter 9/Adjectives.w"
adjective_meaning *Semantics__Adjectives__Meanings__parse(parse_node *q,
int sense,
int adj_name_w1, int adj_name_w2,
int dom_name_w1, int dom_name_w2,
int cond_w1, int cond_w2,
int called_w1, int called_w2) {
adjective_meaning *am = NULL;
if (am == NULL) am = Properties__EitherOr__Adjectives__parse(q, sense,
adj_name_w1, adj_name_w2, dom_name_w1, dom_name_w2, cond_w1, cond_w2, called_w1, called_w2);
if (am == NULL) am = Data__Instances__Adjectives__parse(q, sense,
adj_name_w1, adj_name_w2, dom_name_w1, dom_name_w2, cond_w1, cond_w2, called_w1, called_w2);
if (am == NULL) am = Properties__Measurement__Adjectives__parse(q, sense,
adj_name_w1, adj_name_w2, dom_name_w1, dom_name_w2, cond_w1, cond_w2, called_w1, called_w2);
if (am == NULL) am = Code__Phrases__Adjectives__RawCondition__parse(q, sense,
adj_name_w1, adj_name_w2, dom_name_w1, dom_name_w2, cond_w1, cond_w2, called_w1, called_w2);
if (am == NULL) am = Code__Phrases__Adjectives__RawPhrasal__parse(q, sense,
adj_name_w1, adj_name_w2, dom_name_w1, dom_name_w2, cond_w1, cond_w2, called_w1, called_w2);
if (am == NULL) am = Code__Phrases__Adjectives__Phrasal__parse(q, sense,
adj_name_w1, adj_name_w2, dom_name_w1, dom_name_w2, cond_w1, cond_w2, called_w1, called_w2);
if (am == NULL) am = Code__Phrases__Adjectives__Condition__parse(q, sense,
adj_name_w1, adj_name_w2, dom_name_w1, dom_name_w2, cond_w1, cond_w2, called_w1, called_w2);
return am;
}
#line 1206 "inform7/Chapter 9/Adjectives.w"
void am_compiling_soon(adjective_meaning *am, int T) {
switch (am->adjective_form) {
case CONDITION_KADJ: Code__Phrases__Adjectives__Condition__compiling_soon(am,
RETRIEVE_POINTER_definition(am->detailed_meaning), T); break;
case I6_CONDITION_KADJ: Code__Phrases__Adjectives__RawCondition__compiling_soon(am,
RETRIEVE_POINTER_definition(am->detailed_meaning), T); break;
case I6_ROUTINE_KADJ: Code__Phrases__Adjectives__RawPhrasal__compiling_soon(am,
RETRIEVE_POINTER_definition(am->detailed_meaning), T); break;
case PHRASE_KADJ: Code__Phrases__Adjectives__Phrasal__compiling_soon(am,
RETRIEVE_POINTER_definition(am->detailed_meaning), T); break;
case MEASUREMENT_KADJ: Properties__Measurement__Adjectives__compiling_soon(am,
RETRIEVE_POINTER_measurement_definition(am->detailed_meaning), T); break;
case ENUMERATIVE_KADJ: Data__Instances__Adjectives__compiling_soon(am,
RETRIEVE_POINTER_instance(am->detailed_meaning), T); break;
case EORP_KADJ: Properties__EitherOr__Adjectives__compiling_soon(am,
RETRIEVE_POINTER_property(am->detailed_meaning), T); break;
}
}
#line 1234 "inform7/Chapter 9/Adjectives.w"
int am_compile(adjective_meaning *am, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
am_compiling_soon(am, T);
{
#line 1262 "inform7/Chapter 9/Adjectives.w"
if (Code__Schemas__empty(&(am->i6s_for_runtime_task[T])) == FALSE) {
specification *it_var = Specifications__Storage__new_LOCAL_VARIABLE(-1, -1,
Code__LocalVariables__it_variable());
pcalc_term it_term = Calculus__Terms__new_constant(it_var);
WRITE("(");
Code__Schemas__expand(&(am->i6s_for_runtime_task[T]), OUT, &it_term, NULL);
WRITE(")");
return TRUE;
}
}
#line 1236 "inform7/Chapter 9/Adjectives.w"
;
switch (am->adjective_form) {
case CONDITION_KADJ: return Code__Phrases__Adjectives__Condition__compile(
RETRIEVE_POINTER_definition(am->detailed_meaning), T, OUT, phsf);
case I6_ROUTINE_KADJ: return Code__Phrases__Adjectives__RawPhrasal__compile(
RETRIEVE_POINTER_definition(am->detailed_meaning), T, OUT, phsf);
case I6_CONDITION_KADJ: return Code__Phrases__Adjectives__RawCondition__compile(
RETRIEVE_POINTER_definition(am->detailed_meaning), T, OUT, phsf);
case PHRASE_KADJ: return Code__Phrases__Adjectives__Phrasal__compile(
RETRIEVE_POINTER_definition(am->detailed_meaning), T, OUT, phsf);
case MEASUREMENT_KADJ: return Properties__Measurement__Adjectives__compile(
RETRIEVE_POINTER_measurement_definition(am->detailed_meaning), T, OUT, phsf);
case ENUMERATIVE_KADJ: return Data__Instances__Adjectives__compile(
RETRIEVE_POINTER_instance(am->detailed_meaning), T, OUT, phsf);
case EORP_KADJ: return Properties__EitherOr__Adjectives__compile(
RETRIEVE_POINTER_property(am->detailed_meaning), T, OUT, phsf);
}
internal_error("unknown KADJ code");
return FALSE;
}
#line 1278 "inform7/Chapter 9/Adjectives.w"
int am_assert(adjective_meaning *am, inference_subject *infs_to_assert_on,
specification *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 Code__Phrases__Adjectives__Condition__assert(
RETRIEVE_POINTER_definition(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case I6_CONDITION_KADJ: return Code__Phrases__Adjectives__RawCondition__assert(
RETRIEVE_POINTER_definition(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case I6_ROUTINE_KADJ: return Code__Phrases__Adjectives__RawPhrasal__assert(
RETRIEVE_POINTER_definition(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case PHRASE_KADJ: return Code__Phrases__Adjectives__Phrasal__assert(
RETRIEVE_POINTER_definition(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case MEASUREMENT_KADJ: return Properties__Measurement__Adjectives__assert(
RETRIEVE_POINTER_measurement_definition(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case ENUMERATIVE_KADJ: return Data__Instances__Adjectives__assert(
RETRIEVE_POINTER_instance(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case EORP_KADJ: return Properties__EitherOr__Adjectives__assert(
RETRIEVE_POINTER_property(am->detailed_meaning),
infs_to_assert_on, NULL, parity);
}
internal_error("unknown KADJ code");
return FALSE;
}
#line 1319 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__print_to_index(adjective_meaning *am) {
int rv;
{
#line 1358 "inform7/Chapter 9/Adjectives.w"
if (am->domain_infs) {
int w1 = -1, w2 = -1;
World__Subjects__get_name_text(am->domain_infs, &w1, &w2);
INDEX("(of </i>");
Text__print_raw_text_to_stream(w1, w2, ifl);
INDEX("<i>) ");
}
}
#line 1321 "inform7/Chapter 9/Adjectives.w"
;
if (am->am_negated_from) {
INDEX(" opposite of </i>");
int w1, w2;
Semantics__Adjectives__Meanings__get_text(
am->am_negated_from->owning_adjective, &w1, &w2, FALSE);
Text__print_raw_text_to_stream(w1, w2, ifl);
INDEX("<i>");
} else {
switch (am->adjective_form) {
case CONDITION_KADJ: rv = Code__Phrases__Adjectives__Condition__index(
RETRIEVE_POINTER_definition(am->detailed_meaning)); break;
case I6_CONDITION_KADJ: rv = Code__Phrases__Adjectives__RawCondition__index(
RETRIEVE_POINTER_definition(am->detailed_meaning)); break;
case I6_ROUTINE_KADJ: rv = Code__Phrases__Adjectives__RawPhrasal__index(
RETRIEVE_POINTER_definition(am->detailed_meaning)); break;
case PHRASE_KADJ: rv = Code__Phrases__Adjectives__Phrasal__index(
RETRIEVE_POINTER_definition(am->detailed_meaning)); break;
case MEASUREMENT_KADJ: rv = Properties__Measurement__Adjectives__index(
RETRIEVE_POINTER_measurement_definition(am->detailed_meaning)); break;
case ENUMERATIVE_KADJ: rv = Data__Instances__Adjectives__index(
RETRIEVE_POINTER_instance(am->detailed_meaning)); break;
case EORP_KADJ: rv = Properties__EitherOr__Adjectives__index(
RETRIEVE_POINTER_property(am->detailed_meaning)); break;
default: rv = FALSE; break;
}
if ((rv == FALSE) && (am->index_w1 >= 0))
Text__print_raw_text_to_stream(am->index_w1, am->index_w2, ifl);
}
if (am->index_w1 >= 0) Index__link(am->index_w1);
}
#line 1369 "inform7/Chapter 9/Adjectives.w"
int adaptive_adjective_NTMR(int w1, int w2, int *X, void **XP) {
#line 1370 "inform7/Chapter 9/Adjectives.w"
if (language_of_play == English_language) return FALSE;
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
int aw1, aw2;
Text__Clusters__get_name_general(aph->adjective_names, &aw1, &aw2, language_of_play, 1, -1);
if (Text__compare_word_range(aw1, aw2, w1, w2)) {
*XP = aph; *X = FALSE; return TRUE;
}
}
return FALSE;
}
#line 1385 "inform7/Chapter 9/Adjectives.w"
void Semantics__Adjectives__Meanings__agreements(OUTPUT_STREAM) {
if (language_of_play == English_language) return;
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
int pw1, pw2;
Text__Clusters__get_name_general(aph->adjective_names, &pw1, &pw2, language_of_play, 1, -1);
if (pw1 == -1) continue;
OUT = Code__Routines__begin_numbered(OUT, "AgreeAdjective_%d", aph->allocation_id);
Code__LocalVariables__add_named_call("o");
Code__LocalVariables__add_named_call("force_plural");
Code__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 aw1, aw2;
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;
Text__Clusters__get_name_general(aph->adjective_names, &aw1, &aw2,
language_of_play, number_sought, gender_sought);
if (aw1 >= 0) Text__print_text_to_stream(aw1, aw2, OUT);
else Text__print_text_to_stream(pw1, pw2, OUT);
WRITE("\"; ! %d, %d\n", number_sought, gender_sought);
}
OUTDENT; WRITE("}\n");
OUT = Code__Routines__end(OUT);
}
}
void Semantics__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 177 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *lp_new(kind *K, int spw1, int spw2) {
literal_pattern *lp = CREATE(literal_pattern);
lp->plural_form_only = FALSE;
lp->singular_form_only = FALSE;
lp->kind_specified = K;
lp->prototype_w1 = spw1; lp->prototype_w2 = spw2;
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 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 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.word_ref1 = -1; lpe.word_ref2 = -1;
lpe.preamble_optional = FALSE;
lpe.element_optional = FALSE;
lpe.without_leading_zeros = FALSE;
return lpe;
}
#line 229 "inform7/Chapter 10/Literal Patterns.w"
int C10ZMachineOverflow2_issued = FALSE;
literal_pattern *Semantics__Nouns__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 = lp_list_add_inner(list_head, new_lp);
if ((Code__VirtualMachines__is_16_bit()) && (C10ZMachineOverflow2_issued == FALSE))
for (lp = list_head; lp; lp = lp->next_for_this_kind)
if (Kinds__Scalings__quantum(lp->scaling) > 32767) {
Problems__sentence_problem(_P_(C10ZMachineOverflow2),
"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.)");
C10ZMachineOverflow2_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 *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 (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 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 *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 Semantics__Nouns__LiteralPatterns__scale_factor(kind *K) {
literal_pattern *benchmark_lp = 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 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 *Semantics__Nouns__LiteralPatterns__match(literal_pattern *lp, int w1, int w2, 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 (w2-w1 > lp->prototype_w2-lp->prototype_w1) return NULL;
{
#line 425 "inform7/Chapter 10/Literal Patterns.w"
int tc, wn = w1, wpos = -1, ec = 0, matched_scaledown = 1, parsed_as_real = FALSE;
char *wd = Text__word_text(w1);
for (tc=0; tc<lp->no_lp_tokens; tc++) {
if (wn > w2) {
if ((wpos == -1) /* i.e., if we are cleanly at a word boundary */
&& (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 = Text__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 = Text__word_text(wn); } /* start parsing the interior of a word */
if (wd[wpos] == '-') { sign_used_at = lpe; wpos++; }
if (Kinds__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 (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;
int wn = lexer_wordcount;
Text__feed_into_lexer(real_buffer, FALSE, NULL);
if ((point_at == -1) && (mult_at == -1)) {
if (parse_nt_against_word_range(cardinal_number_NTM, wn, wn, 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 = construct_float(signbit, matched_number, 0, 0);
} else {
if (parse_nt_against_word_range(literal_real_in_digits_NTM, wn, wn, 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 = 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 <= w2) 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 662 "inform7/Chapter 10/Literal Patterns.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_words(3, lp->prototype_w1, lp->prototype_w2);
Problems__handmade_problem(_P_(C10LPTooLittleAccuracy));
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 590 "inform7/Chapter 10/Literal Patterns.w"
if (sign_used_at->element_index != 0) {
ISSUING_LP_PROBLEM;
Problems__sentence_problem(_P_(C10NegationInternal),
"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__sentence_problem(_P_(C10NegationForbidden),
"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 633 "inform7/Chapter 10/Literal Patterns.w"
int max = element_overflow_at->element_range - 1;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_words(3, lp->prototype_w1, lp->prototype_w2);
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__handmade_problem(_P_(C10ElementOverflow));
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 610 "inform7/Chapter 10/Literal Patterns.w"
if (overflow_32_bit_flag) {
ISSUING_LP_PROBLEM;
Problems__sentence_problem(_P_(C10EvenOverflow-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) && (Code__VirtualMachines__is_16_bit())) {
ISSUING_LP_PROBLEM;
Problems__sentence_problem(_P_(C10ZMachineOverflow),
"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 683 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__gpr_locals(void) {
Code__LocalVariables__add_internal_local("wpos");
Code__LocalVariables__add_internal_local("mid_word");
Code__LocalVariables__add_internal_local("matched_number");
Code__LocalVariables__add_internal_local("cur_word");
Code__LocalVariables__add_internal_local("cur_len");
Code__LocalVariables__add_internal_local("cur_addr");
Code__LocalVariables__add_internal_local("sgn");
Code__LocalVariables__add_internal_local("tot");
Code__LocalVariables__add_internal_local("f");
Code__LocalVariables__add_internal_local("x");
}
#line 702 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__gpr(OUTPUT_STREAM, literal_pattern *lp) {
int label = lp->allocation_id;
int tc, ec;
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 (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 750 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (mid_word) jump Failed_LP_%d;\n", label);
WRITE("if (cur_word ~= ");
Formats__Inform6__compile_dictionary_word(OUT,
Text__word_text(lp->lp_tokens[tc].token_wn), FALSE);
WRITE(") jump Failed_LP_%d;\n", label);
WRITE("wn++;\n");
}
#line 723 "inform7/Chapter 10/Literal Patterns.w"
; break;
case CHARACTER_LPT:
{
#line 760 "inform7/Chapter 10/Literal Patterns.w"
{
#line 861 "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 760 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("if (cur_addr->wpos++ ~= '%c') jump Failed_LP_%d;\n",
Platform__tolower(lp->lp_tokens[tc].token_char), label);
{
#line 871 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (wpos == cur_len) {\n"); INDENT;
WRITE("wn++; mid_word = false;\n");
OUTDENT; WRITE("}\n");
}
#line 763 "inform7/Chapter 10/Literal Patterns.w"
;
}
#line 724 "inform7/Chapter 10/Literal Patterns.w"
; break;
case ELEMENT_LPT:
{
#line 768 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_element *lpe = &(lp->lp_elements[ec++]);
{
#line 861 "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 769 "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__uses_floating_point(lp->kind_specified))
{
#line 784 "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 861 "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 795 "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 861 "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 803 "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 861 "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 810 "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 776 "inform7/Chapter 10/Literal Patterns.w"
else
{
#line 826 "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 861 "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 848 "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 778 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 871 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (wpos == cur_len) {\n"); INDENT;
WRITE("wn++; mid_word = false;\n");
OUTDENT; WRITE("}\n");
}
#line 779 "inform7/Chapter 10/Literal Patterns.w"
;
}
#line 725 "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__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: ");
Text__print_text_to_stream(lp->prototype_w1, lp->prototype_w2, OUT);
WRITE("]^\"; }\n");
WRITE("#endif;\n");
WRITE("return GPR_NUMBER;\n");
WRITE(".Failed_LP_%d;\n", label);
}
#line 878 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__index_all(kind *K) {
literal_pattern *lp, *benchmark_lp = 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 898 "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)) {
index_lp_possibilities(lp, benchmark_lp);
} else {
Text__print_raw_text_to_stream(lp->prototype_w1, lp->prototype_w2, ifl);
}
f = TRUE;
}
}
#line 887 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 914 "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>");
index_lp_possibilities(lp, benchmark_lp);
f = TRUE;
}
}
#line 888 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 926 "inform7/Chapter 10/Literal Patterns.w"
int f = FALSE;
literal_pattern_name *lpn;
LOOP_OVER(lpn, literal_pattern_name)
if (lpn->word_ref1 >= 0) {
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;
Text__print_raw_text_to_stream(lpn->word_ref1, lpn->word_ref2, ifl);
goto NextLPN;
}
}
NextLPN: ;
}
}
#line 889 "inform7/Chapter 10/Literal Patterns.w"
;
}
#line 951 "inform7/Chapter 10/Literal Patterns.w"
void index_lp_possibilities(literal_pattern *lp, literal_pattern *benchmark_lp) {
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;");
index_lp_possibility(lp, benchmark_lp);
if (lp->equivalent_unit) {
INDEX(" <i>where</i> ");
lp_index_quantum_value(lp, lp->scaling);
INDEX(" = ");
lp_index_quantum_value(benchmark_lp, lp->scaling);
} else {
if (Kinds__Scalings__compare(lp->scaling, benchmark_lp->scaling) < 0) {
INDEX(" <i>where</i> ");
lp_index_quantum_value(lp, benchmark_lp->scaling);
INDEX(" = ");
lp_index_quantum_value(benchmark_lp, benchmark_lp->scaling);
}
if (Kinds__Scalings__compare(lp->scaling, benchmark_lp->scaling) > 0) {
INDEX(" <i>where</i> ");
lp_index_quantum_value(lp, lp->scaling);
INDEX(" = ");
lp_index_quantum_value(benchmark_lp, lp->scaling);
}
}
}
#line 979 "inform7/Chapter 10/Literal Patterns.w"
void index_lp_possibility(literal_pattern *lp, literal_pattern *benchmark_lp) {
if (lp == benchmark_lp) INDEX("<b>");
if (lp->plural_form_only)
lp_index_quantum_value(lp, Kinds__Scalings__enlarge(lp->scaling, 2));
else
lp_index_quantum_value(lp, lp->scaling);
if (lp == benchmark_lp) INDEX("</b>");
if (lp->next_alternative_lp) {
INDEX(" <i>or</i> ");
index_lp_possibility(lp->next_alternative_lp, benchmark_lp);
}
}
#line 998 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__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) {
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)) {
lp_index_value_specific(lp, v); return;
}
}
}
}
if (lp_possibility) lp_index_value_specific(lp_possibility, v);
else lp_index_value_specific(lp_list, v);
}
#line 1029 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__index_benchmark_value(kind *K) {
literal_pattern *lp;
LITERAL_FORMS_LOOP(lp, K)
if (lp->benchmark) {
lp_index_quantum_value(lp, lp->scaling);
return;
}
INDEX("1");
}
#line 1043 "inform7/Chapter 10/Literal Patterns.w"
void lp_index_quantum_value(literal_pattern *lp, scaling_transformation sc) {
int v = 0;
double real_v = 0.0;
if (Kinds__uses_floating_point(lp->kind_specified))
real_v = Kinds__Scalings__real_quantum(sc);
else
v = Kinds__Scalings__quantum(sc);
lp_index_value_specific_inner(lp, v, real_v);
}
void lp_index_value_specific(literal_pattern *lp, double alt_value) {
int v = (int) alt_value;
double real_v = alt_value;
lp_index_value_specific_inner(lp, v, real_v);
}
void 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 1077 "inform7/Chapter 10/Literal Patterns.w"
if (tc > 0) INDEX(" ");
Text__print_literal_string_to_file(ifl, Text__word_raw_text(lp->lp_tokens[tc].token_wn));
}
#line 1065 "inform7/Chapter 10/Literal Patterns.w"
; break;
case CHARACTER_LPT:
{
#line 1083 "inform7/Chapter 10/Literal Patterns.w"
Formats__HTML__html_char_out(ifl, lp->lp_tokens[tc].token_char);
}
#line 1066 "inform7/Chapter 10/Literal Patterns.w"
; break;
case ELEMENT_LPT:
{
#line 1088 "inform7/Chapter 10/Literal Patterns.w"
if (Kinds__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 = leading_zero_prototype(lpe->element_range);
INDEX(prototype, (v/(lpe->element_multiplier)) % (lpe->element_range));
}
if (ec == 0)
{
#line 1108 "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(leading_zero_prototype(ranger), remainder);
}
}
#line 1101 "inform7/Chapter 10/Literal Patterns.w"
;
}
ec++;
}
#line 1067 "inform7/Chapter 10/Literal Patterns.w"
; break;
default: internal_error("unknown literal pattern token type");
}
}
}
#line 1122 "inform7/Chapter 10/Literal Patterns.w"
char *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 1138 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__LiteralPatterns__printing_routine(OUTPUT_STREAM, literal_pattern *lp_list) {
literal_pattern_name *lpn;
literal_pattern *lp;
int k;
Code__LocalVariables__add_named_call("which");
Code__LocalVariables__add_internal_local("rem");
Code__LocalVariables__add_internal_local("S");
LOOP_OVER(lpn, literal_pattern_name) {
if (lpn->word_ref1 >= 0) {
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: ");
Text__print_text_to_stream(lpn->word_ref1, lpn->word_ref2, OUT);
WRITE("\n");
WRITE("if (which == %d) {\n", lpn->allocation_id + 1);
{
#line 1193 "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 1162 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("}\n\n");
}
}
}
{
#line 1183 "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 1168 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1193 "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 1169 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("return;\n");
for (lp = lp_list; lp; lp = lp->next_for_this_kind) {
{
#line 1228 "inform7/Chapter 10/Literal Patterns.w"
int tc, ec=0, oc=0;
WRITE("\n");
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 1293 "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 1234 "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 1248 "inform7/Chapter 10/Literal Patterns.w"
WRITE("print \"");
Formats__Inform6__compile_string(OUT, Text__word_raw_text(lp->lp_tokens[tc].token_wn), 0);
WRITE("\";\n");
}
#line 1238 "inform7/Chapter 10/Literal Patterns.w"
; break;
case CHARACTER_LPT:
{
#line 1255 "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 \"");
Formats__Inform6__compile_string(OUT, tiny_string, 0);
WRITE("\";\n");
}
#line 1239 "inform7/Chapter 10/Literal Patterns.w"
; break;
case ELEMENT_LPT:
{
#line 1264 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_element *lpe = &(lp->lp_elements[ec]);
if (lpe->element_optional)
{
#line 1293 "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 1266 "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 1240 "inform7/Chapter 10/Literal Patterns.w"
; break;
default: internal_error("unknown literal pattern token type");
}
}
}
#line 1174 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("return;\n");
}
}
#line 1307 "inform7/Chapter 10/Literal Patterns.w"
void comment_use_of_lp(OUTPUT_STREAM, literal_pattern *lp) {
WRITE("! ");
Text__print_text_to_stream(lp->prototype_w1, lp->prototype_w2, OUT);
WRITE(", ");
Kinds__Scalings__describe(OUT, lp->scaling);
WRITE("\n");
}
#line 1318 "inform7/Chapter 10/Literal Patterns.w"
void 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);
comment_use_of_lp(OUT, lp);
}
#line 1340 "inform7/Chapter 10/Literal Patterns.w"
sentence_handler SPECIFIES_SH_handler =
{ SENTENCE_NT, SPECIFIES_VB, 1, new_literal_specification };
void new_literal_specification(parse_node *pn) {
new_literal_specification_list(pn->down->next, pn->down->next->next, NULL);
}
#line 1357 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *new_literal_specification_list(parse_node *p, parse_node *q,
literal_pattern *lp_main) {
if (Parser__Nodes__type(p) == AND_NT) {
lp_main = new_literal_specification_list(p->down, q, lp_main);
return new_literal_specification_list(p->down->next, q, lp_main);
}
return new_literal_specification_inner(p, q, lp_main);
}
#line 1376 "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;
int LP_equivalent; kind *LP_equivalent_kind;
int LP_offset; kind *LP_offset_kind;
kind *LP_left_kind, *LP_right_kind; /* used only for dimensional rules */
kind *LP_kind_specified; /* what kind this sentence specifies */
#line 1386 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *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;
int spw1 = p->word_ref1, spw2 = p->word_ref2;
{
#line 1448 "inform7/Chapter 10/Literal Patterns.w"
LP_scaling = LP_SCALED_UP; LP_scaling_amount = 1; LP_real_scaling_amount = 1.0;
LP_equivalent = 0; LP_real_equivalent = 0.0; LP_equivalent_kind = NULL;
LP_offset = 0; LP_real_offset = 0.0; LP_offset_kind = NULL;
parse_nt_against_word_range(specifies_sentence_subject_NTM, spw1, spw2, NULL, NULL);
GET_RW(specifies_sentence_subject_NTM, 1, spw1, spw2);
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 1395 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1544 "inform7/Chapter 10/Literal Patterns.w"
LP_offset_kind = NULL;
parse_nt_against_word_range(specifies_sentence_object_NTM, q->word_ref1, q->word_ref2, 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 1396 "inform7/Chapter 10/Literal Patterns.w"
;
if (Kinds__uses_floating_point(K)) integer_scaling = FALSE;
{
#line 1702 "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 1400 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1682 "inform7/Chapter 10/Literal Patterns.w"
waive_lp_overflows = TRUE;
kind *K = NULL; if (parse_nt_against_word_range(literal_NTM, spw1, spw2, NULL, NULL)) K = most_recent_result_p;
waive_lp_overflows = FALSE;
if (K) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__quote_words(3, spw1, spw2);
Problems__handmade_problem(_P_(C10DuplicateUnitSpec));
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 1401 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1711 "inform7/Chapter 10/Literal Patterns.w"
if (Kinds__is_built_in(K)) {
Problems__sentence_problem(_P_(C10LPBuiltInKOV),
"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__convert_to_unit(K) == FALSE) {
Problems__sentence_problem(_P_(C10LPEnumeration),
"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 1402 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1643 "inform7/Chapter 10/Literal Patterns.w"
if (LP_equivalent_kind) {
if (Kinds__eq(LP_equivalent_kind, K)) {
scaled_dir = LP_SCALED_UP; scaled = LP_equivalent;
} else {
Problems__sentence_problem_with_note(_P_(C10BadLPEquivalent),
"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_kind) {
if (Kinds__eq(LP_offset_kind, K)) {
offset = LP_offset;
} else {
Problems__sentence_problem_with_note(_P_(C10BadLPOffset),
"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 1403 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1728 "inform7/Chapter 10/Literal Patterns.w"
lp = lp_new(K, spw1, spw2);
if (LP_equivalent_kind) LP_real_scaling_amount = LP_real_equivalent;
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_kind) 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 1404 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1747 "inform7/Chapter 10/Literal Patterns.w"
int i, j, tc, ec;
for (i=0, tc=0, ec=0; spw1+i<=spw2; i++) {
literal_pattern_token new_token;
int digit_found = FALSE;
char *text_of_word = Text__word_raw_text(spw1+i);
for (j=0; text_of_word[j]; j++) if (isdigit(text_of_word[j])) digit_found = TRUE;
if (digit_found)
{
#line 1776 "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__sentence_problem(_P_(C10LPElementTooLarge),
"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 = lpe_new(ec, tot+1, sgn);
if (ec >= MAX_ELEMENTS_PER_LITERAL) {
Problems__sentence_problem(_P_(C10LPTooManyElements),
"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 = lpt_new(ELEMENT_LPT, next_token_begins_word);
{
#line 1827 "inform7/Chapter 10/Literal Patterns.w"
if (tc >= MAX_TOKENS_PER_LITERAL) {
Problems__sentence_problem(_P_(C10LPTooComplicated),
"that specification is too complicated",
"and will have to be shortened.");
return owner;
}
lp->lp_tokens[tc++] = new_token;
}
#line 1810 "inform7/Chapter 10/Literal Patterns.w"
;
j--;
} else {
new_token = lpt_new(CHARACTER_LPT, next_token_begins_word);
new_token.token_char = text_of_word[j];
{
#line 1827 "inform7/Chapter 10/Literal Patterns.w"
if (tc >= MAX_TOKENS_PER_LITERAL) {
Problems__sentence_problem(_P_(C10LPTooComplicated),
"that specification is too complicated",
"and will have to be shortened.");
return owner;
}
lp->lp_tokens[tc++] = new_token;
}
#line 1815 "inform7/Chapter 10/Literal Patterns.w"
;
}
sgn = 1; next_token_begins_word = FALSE;
}
}
#line 1754 "inform7/Chapter 10/Literal Patterns.w"
else {
new_token = lpt_new(WORD_LPT, TRUE);
new_token.token_wn = spw1+i;
{
#line 1827 "inform7/Chapter 10/Literal Patterns.w"
if (tc >= MAX_TOKENS_PER_LITERAL) {
Problems__sentence_problem(_P_(C10LPTooComplicated),
"that specification is too complicated",
"and will have to be shortened.");
return owner;
}
lp->lp_tokens[tc++] = new_token;
}
#line 1758 "inform7/Chapter 10/Literal Patterns.w"
;
}
}
lp->no_lp_tokens = tc;
lp->no_lp_elements = ec;
if (lp->no_lp_elements == 0) {
Problems__sentence_problem(_P_(C10LPWithoutElement),
"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 1405 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1838 "inform7/Chapter 10/Literal Patterns.w"
if (integer_scaling == FALSE) {
Kinds__convert_to_real(K);
Kinds__Scalings__convert_to_real(&(lp->scaling));
}
}
#line 1406 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1848 "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 1407 "inform7/Chapter 10/Literal Patterns.w"
;
if (Kinds__list_of_literal_forms(K) == NULL) lp->benchmark = TRUE;
Kinds__add_literal_pattern(K, lp);
if (part_np_list) {
{
#line 1858 "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->word_ref1 = p->word_ref1; lpe->word_ref2 = p->word_ref2;
int O = Parser__Nodes__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 > 0) && (i != lp->no_lp_elements)) {
Problems__sentence_problem(_P_(C10LPNotAllNamed),
"you must supply names for all the parts",
"if for any");
return owner;
}
}
#line 1413 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1881 "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__sentence_problem(_P_(C10LPFirstOptional),
"the first part is not allowed to be optional",
"since it is needed to identify the value.");
return owner;
}
}
if (opt_count >= 2) {
Problems__sentence_problem(_P_(C10LPMultipleOptional),
"only one part can be called optional",
"since if any part is omitted then so are all subsequent parts.");
return owner;
}
}
#line 1414 "inform7/Chapter 10/Literal Patterns.w"
;
define_packing_phrases(lp, K);
}
if (owner == NULL) owner = lp;
else
{
#line 1426 "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 1419 "inform7/Chapter 10/Literal Patterns.w"
;
return owner;
}
#line 1488 "inform7/Chapter 10/Literal Patterns.w"
int specifies_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 1519 "inform7/Chapter 10/Literal Patterns.w"
*X = ABANDON_LPN; *XP = NULL;
if (preform_lookahead_mode == FALSE) {
Problems__sentence_problem(_P_(C10MultiplyingNonKOVs),
"only kinds of value can be multiplied here",
"and only in a sentence like 'A length times a length specifies an area.'");
}
}
#line 1491 "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 1493 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_group_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = R[1] | R[2];
{
#line 1512 "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 1495 "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 1497 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_group_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 1501 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_group_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = new_lpn(-1, -1, RP[1]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = IN_LPN; *XP = new_lpn(w1, w2, NULL);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 1529 "inform7/Chapter 10/Literal Patterns.w"
*X = ABANDON_LPN; *XP = NULL;
if (preform_lookahead_mode == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C10BadLPNameOption));
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 1507 "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 1508 "inform7/Chapter 10/Literal Patterns.w"
#line 1558 "inform7/Chapter 10/Literal Patterns.w"
int specifies_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 1561 "inform7/Chapter 10/Literal Patterns.w"
int kind_specified_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 1584 "inform7/Chapter 10/Literal Patterns.w"
if (preform_lookahead_mode == FALSE) {
Problems__sentence_problem(_P_(C10LPNotKOV),
"you can only specify ways to write kinds of value",
"as created with sentences like 'A weight is a kind of value.'");
}
}
#line 1564 "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 1565 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_specification_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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_offset = R[2]; LP_real_offset = latest_constructed_real; LP_offset_kind = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = OFFSET_LPC; LP_offset = R[1]; LP_real_offset = latest_constructed_real; LP_offset_kind = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = EQUIVALENT_LPC; LP_equivalent = R[1]; LP_real_equivalent = latest_constructed_real; LP_equivalent_kind = 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 1572 "inform7/Chapter 10/Literal Patterns.w"
int scaling_instruction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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;;
#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;;
#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;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1580 "inform7/Chapter 10/Literal Patterns.w"
#line 1599 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1602 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 1606 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1]; if (RP[1]) Parser__Nodes__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 1610 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_option_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 1614 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_option_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 1618 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_option_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 1628 "inform7/Chapter 10/Literal Patterns.w"
*X = 0;
if (preform_lookahead_mode == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C10BadLPPartOption));
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 1623 "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 1624 "inform7/Chapter 10/Literal Patterns.w"
#line 1903 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_group_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 1904 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_name *lpn;
LOOP_OVER(lpn, literal_pattern_name) {
if (Text__compare_word_range(lpn->word_ref1, lpn->word_ref2, w1, w2)) {
*XP = lpn; return TRUE;
}
}
return FALSE;
}
#line 1920 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_name *new_lpn(int w1, int w2, literal_pattern_name *existing) {
if (preform_lookahead_mode) return NULL;
literal_pattern_name *new = CREATE(literal_pattern_name);
new->word_ref1 = w1; new->word_ref2 = w2;
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 1940 "inform7/Chapter 10/Literal Patterns.w"
void Semantics__Nouns__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 (lpn->word_ref1 >= 0) {
literal_pattern_name *lpn2;
for (lpn2 = lpn; lpn2; lpn2 = lpn2->next)
if (lpn2->lpn_compiled_already == FALSE)
{
#line 1969 "inform7/Chapter 10/Literal Patterns.w"
kind *K = lpn2->can_use_this_lp->kind_specified;
TEMPORARY_STREAM;
Kinds__Textual__write(TEMP, K);
int name1 = lpn->word_ref1, name2 = lpn->word_ref2;
int x1 = lexer_wordcount, x2;
Text__feed_into_lexer("To say ( val - ", FALSE, NULL);
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
Text__feed_into_lexer(" ) ", FALSE, NULL);
Text__splice_words(name1, name2);
x2 = lexer_wordcount-1;
Parser__Sentences__make_node(x1, x2, ':', NULL);
x1 = lexer_wordcount;
char print_rule_buff[1024];
sprintf(print_rule_buff, " (- %s({val}, %d); -) ",
Kinds__get_name_of_printing_rule(K), lpn->allocation_id + 1);
Text__feed_into_lexer(print_rule_buff, FALSE, NULL);
x2 = lexer_wordcount-1;
Parser__Sentences__make_node(x1, x2, '.', NULL);
CLOSE_TEMPORARY_STREAM;
literal_pattern_name *lpn3;
for (lpn3 = lpn2; lpn3; lpn3 = lpn3->next)
if (Kinds__eq(K, lpn3->can_use_this_lp->kind_specified))
lpn3->lpn_compiled_already = TRUE;
}
#line 1949 "inform7/Chapter 10/Literal Patterns.w"
;
}
}
Parser__Sentences__register_recently_lexed_phrases();
}
#line 1999 "inform7/Chapter 10/Literal Patterns.w"
void define_packing_phrases(literal_pattern *lp, kind *K) {
TEMPORARY_STREAM;
Kinds__Textual__write(TEMP, K);
{
#line 2022 "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]);
int x1, x2;
char print_rule_buff[1024];
x1 = lexer_wordcount;
Text__feed_into_lexer("To decide which number is ", FALSE, NULL);
Text__splice_words(lpe->word_ref1, lpe->word_ref2);
Text__feed_into_lexer(" part of ( full - ", FALSE, NULL);
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
Text__feed_into_lexer(" ) ", FALSE, NULL);
x2 = lexer_wordcount-1;
Parser__Sentences__make_node(x1, x2, ':', NULL);
x1 = lexer_wordcount;
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);
Text__feed_into_lexer(print_rule_buff, FALSE, NULL);
x2 = lexer_wordcount-1;
Parser__Sentences__make_node(x1, x2, '.', NULL);
}
}
#line 2002 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 2055 "inform7/Chapter 10/Literal Patterns.w"
if (lp->no_lp_elements > 0) {
int i, x1, x2;
char print_rule_buff[1024];
x1 = lexer_wordcount;
Text__feed_into_lexer("To decide which ", FALSE, NULL);
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
Text__feed_into_lexer(" is ", FALSE, NULL);
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
Text__feed_into_lexer(" with ", FALSE, NULL);
for (i=0; i<lp->no_lp_elements; i++) {
literal_pattern_element *lpe = &(lp->lp_elements[i]);
sprintf(print_rule_buff, " part%d ", i);
Text__splice_words(lpe->word_ref1, lpe->word_ref2);
Text__feed_into_lexer(" part ( ", FALSE, NULL);
Text__feed_into_lexer(print_rule_buff, FALSE, NULL);
Text__feed_into_lexer(" - a number ) ", FALSE, NULL);
}
x2 = lexer_wordcount-1;
Parser__Sentences__make_node(x1, x2, ':', NULL);
x1 = lexer_wordcount;
sprintf(print_rule_buff, " (- (");
for (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), ") -) ");
Text__feed_into_lexer(print_rule_buff, FALSE, NULL);
x2 = lexer_wordcount-1;
Parser__Sentences__make_node(x1, x2, '.', NULL);
}
}
#line 2003 "inform7/Chapter 10/Literal Patterns.w"
;
Parser__Sentences__register_recently_lexed_phrases();
CLOSE_TEMPORARY_STREAM;
}
#line 44 "inform7/Chapter 10/Times of Day.w"
void Plugins__Times__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, times_new_base_kind_notify);
}
#line 51 "inform7/Chapter 10/Times of Day.w"
int times_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) {
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 *Plugins__Times__kind(void) {
if (K_time == NULL) return NULL;
return K_time;
}
#line 72 "inform7/Chapter 10/Times of Day.w"
int literal_time_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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
default: *X = R[0]; break;
}
return TRUE;
}
#line 76 "inform7/Chapter 10/Times of Day.w"
int elapsed_time_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 81 "inform7/Chapter 10/Times of Day.w"
int clock_time_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 97 "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
case 1:
{
#line 97 "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 84 "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 85 "inform7/Chapter 10/Times of Day.w"
int am_pm_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 89 "inform7/Chapter 10/Times of Day.w"
#line 112 "inform7/Chapter 10/Times of Day.w"
int digital_clock_time_NTMR(int w1, int w2, int *X, void **XP) {
#line 113 "inform7/Chapter 10/Times of Day.w"
int time_minutes = 0, time_hours = 0;
int ratchet = 0, t, colons = 0, digits = 0;
char *wd = Text__word_text(w1);
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 140 "inform7/Chapter 10/Times of Day.w"
int continental_clock_time_NTMR(int w1, int w2, int *X, void **XP) {
#line 141 "inform7/Chapter 10/Times of Day.w"
int time_minutes = 0, time_hours = 0;
int ratchet = 0, t, colons = 0, digits = 0;
char *wd = Text__word_text(w1);
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 168 "inform7/Chapter 10/Times of Day.w"
int event_rule_preamble_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 177 "inform7/Chapter 10/Times of Day.w"
Problems__sentence_problem(_P_(C10AtTimeThat),
"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 171 "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 187 "inform7/Chapter 10/Times of Day.w"
Problems__sentence_problem(_P_(C10AtWithoutTime),
"'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 172 "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 173 "inform7/Chapter 10/Times of Day.w"
#line 165 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning *Semantics__Nouns__ExcerptMeanings__new(unsigned int mc,
unsigned int smc, general_pointer data) {
excerpt_meaning *em = CREATE(excerpt_meaning);
em->meaning_code = mc;
em->secondary_code = smc;
em->data = data;
em->no_em_tokens = 0;
em->excerpt_hash = 0;
return em;
}
#line 179 "inform7/Chapter 10/Excerpt Meanings.w"
unsigned int Semantics__Nouns__ExcerptMeanings__get_secondary_code(excerpt_meaning *em) {
if (em->meaning_code != MISCELLANEOUS_MC)
internal_error("looked up SMC for non-miscellaneous EM");
return em->secondary_code;
}
general_pointer Semantics__Nouns__ExcerptMeanings__data(excerpt_meaning *em) {
return em->data;
}
#line 192 "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 ACTIVITY_MC: LOG("ACTIVITY_MC"); break;
case ADJECTIVE_MC: LOG("ADJECTIVE_MC"); break;
case COND_PHRASE_MC: LOG("COND_PHRASE_MC"); break;
case END_PHRASE_MC: LOG("END_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 235 "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 (Text__Vocabulary__get_exemplar(em->em_tokens[i], FALSE) == NULL)
internal_error("Null token in EM");
LOG("%s", Text__Vocabulary__get_exemplar(em->em_tokens[i], FALSE));
}
LOG(" = $p", em->meaning_code);
if (em->secondary_code) LOG(" (secondary=%d)", em->secondary_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 280 "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 = Text__word(i);
if (v)
{
#line 334 "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"
;
}
return h;
}
#line 309 "inform7/Chapter 10/Excerpt Meanings.w"
void 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 = Text__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 334 "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 321 "inform7/Chapter 10/Excerpt Meanings.w"
;
}
em->excerpt_hash = h;
}
#line 402 "inform7/Chapter 10/Excerpt Meanings.w"
meaning_list *blank_says_ml = NULL;
void register_em(unsigned int meaning_code, excerpt_meaning *em) {
Specifications__warn_expression_cache(); /* the existence of new meanings jeopardises any cached parsing results */
{
#line 433 "inform7/Chapter 10/Excerpt Meanings.w"
hash_code_from_token_list(em);
}
#line 406 "inform7/Chapter 10/Excerpt Meanings.w"
;
{
#line 449 "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 407 "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 459 "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 (Text__Languages__test_vocabulary(v, article_NTM)) continue;
meaning_list *ml = Parser__SP__MeaningLists__new_permanent(em->meaning_code);
ml->em = em;
ml->next_alternative = v->subset_list;
v->subset_list = ml;
v->subset_list_length++;
}
}
#line 414 "inform7/Chapter 10/Excerpt Meanings.w"
;
} else if ((em->no_em_tokens == 1) && (em->em_tokens[0] == NULL) &&
(meaning_code == SAY_PHRASE_MC)) {
{
#line 478 "inform7/Chapter 10/Excerpt Meanings.w"
meaning_list *ml = Parser__SP__MeaningLists__new_permanent(em->meaning_code); ml->em = em;
if (blank_says_ml) {
meaning_list *ml2 = blank_says_ml;
while (ml2->next_alternative) ml2 = ml2->next_alternative;
ml2->next_alternative = ml;
}
else blank_says_ml = ml;
LOGIF(EXCERPT_MEANINGS,
"The blank list with $M is now:\n$m", em, blank_says_ml);
}
#line 417 "inform7/Chapter 10/Excerpt Meanings.w"
;
} else if (em->em_tokens[0]) {
{
#line 491 "inform7/Chapter 10/Excerpt Meanings.w"
meaning_list *ml = Parser__SP__MeaningLists__new_permanent(em->meaning_code); ml->em = em;
ml->next_alternative = em->em_tokens[0]->start_list;
em->em_tokens[0]->start_list = ml;
}
#line 419 "inform7/Chapter 10/Excerpt Meanings.w"
;
} else if (em->em_tokens[em->no_em_tokens-1]) {
{
#line 498 "inform7/Chapter 10/Excerpt Meanings.w"
meaning_list *ml = Parser__SP__MeaningLists__new_permanent(em->meaning_code); ml->em = em;
ml->next_alternative = em->em_tokens[em->no_em_tokens-1]->end_list;
em->em_tokens[em->no_em_tokens-1]->end_list = ml;
}
#line 421 "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 505 "inform7/Chapter 10/Excerpt Meanings.w"
meaning_list *ml = Parser__SP__MeaningLists__new_permanent(em->meaning_code); ml->em = em;
ml->next_alternative = em->em_tokens[i]->middle_list;
em->em_tokens[i]->middle_list = ml;
}
#line 425 "inform7/Chapter 10/Excerpt Meanings.w"
; break; }
if (i >= em->no_em_tokens-1) internal_error("registered meaning of two or more #s");
}
}
#line 514 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning *Semantics__Nouns__ExcerptMeanings__register(
unsigned int meaning_code, unsigned int secondary,
int w1, int w2, general_pointer data) {
if (!((0 <= w1) && (w1 <= w2) && (w2 < lexer_wordcount))) {
LOG("Invalid word range %d-%d\n", w1, w2);
internal_error("tried to register excerpt meaning out of range");
}
if (meaning_code == NAMETAG_MC) {
int i;
for (i = w1; i <= w2; i++) Text__Languages__mark_word(i, s_instance_name_NTM);
}
if (meaning_code == KIND_SLOW_MC) {
int i;
for (i = w1; i <= w2; i++) Text__Languages__mark_word(i, k_kind_NTM);
}
excerpt_meaning *em = Semantics__Nouns__ExcerptMeanings__new(meaning_code, secondary, data);
{
#line 551 "inform7/Chapter 10/Excerpt Meanings.w"
if ((meaning_code & PARAMETRISED_PARSING_BITMAP) == 0) {
if (Text__Languages__test_word(w1, article_NTM)) w1++;
if (w1 > w2) internal_error("registered a meaning which was only an article");
}
}
#line 532 "inform7/Chapter 10/Excerpt Meanings.w"
;
if (meaning_code == SAY_PHRASE_MC)
{
#line 573 "inform7/Chapter 10/Excerpt Meanings.w"
char *tx = Text__word_raw_text(w1);
if ((tx[0]) && (isupper(tx[0]))) {
vocabulary_entry *ucf = Text__Vocabulary__make_case_sensitive(Text__word(w1));
Text__set_word(w1, ucf);
LOGIF(EXCERPT_MEANINGS,
"Allowing initial capitalised word %s: meaning_code = %08x\n",
tx, meaning_code);
}
}
#line 535 "inform7/Chapter 10/Excerpt Meanings.w"
;
{
#line 594 "inform7/Chapter 10/Excerpt Meanings.w"
int i, tc;
for (i=0, tc=0; w1+i<=w2; i++) {
if (tc >= MAX_TOKENS_PER_EXCERPT_MEANING) {
{
#line 663 "inform7/Chapter 10/Excerpt Meanings.w"
Problems__sentence_problem(_P_(C10TooLongName),
"that seems to involve far too long a name",
"since in general names are limited to a maximum of 32 words.");
}
#line 597 "inform7/Chapter 10/Excerpt Meanings.w"
;
break;
}
if (compare_word(w1+i, OPENBRACKET_V)) {
em->em_tokens[tc++] = NULL;
{
#line 611 "inform7/Chapter 10/Excerpt Meanings.w"
int bl = 1; i++;
while (bl > 0) {
if (w1+i>w2) {
LOG("Bad meaning: <$W>\n", w1, w2);
internal_error("Bracket mismatch when registering");
}
if (compare_word(w1+i, OPENBRACKET_V)) bl++;
if (compare_word(w1+i, CLOSEBRACKET_V)) bl--;
i++;
}
if ((w1+i <= w2) && (compare_word(w1+i, OPENBRACKET_V))) {
LOG("Bad meaning: <$W>\n", w1, w2);
internal_error("Two consecutive bracketed tokens when registering");
}
i--;
}
#line 602 "inform7/Chapter 10/Excerpt Meanings.w"
;
} else em->em_tokens[tc++] = Text__word(w1+i);
}
em->no_em_tokens = tc;
}
#line 537 "inform7/Chapter 10/Excerpt Meanings.w"
;
register_em(meaning_code, em);
if ((parse_nt_against_word_range(notable_player_variables_NTM, w1, w2, NULL, NULL)) && (most_recent_result == 0)
&& (meaning_code & VARIABLE_MC)) meaning_of_player = em;
return em;
}
#line 636 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning *Semantics__Nouns__ExcerptMeanings__register_assemblage(
unsigned int meaning_code, unsigned int secondary, word_assemblage wa, general_pointer data) {
excerpt_meaning *em = Semantics__Nouns__ExcerptMeanings__new(meaning_code, secondary, data);
vocabulary_entry **array; int len;
Text__Words__as_array(&wa, &array, &len);
int i, tc = 0;
for (i=0; i<len; i++) {
if (tc >= MAX_TOKENS_PER_EXCERPT_MEANING) {
{
#line 663 "inform7/Chapter 10/Excerpt Meanings.w"
Problems__sentence_problem(_P_(C10TooLongName),
"that seems to involve far too long a name",
"since in general names are limited to a maximum of 32 words.");
}
#line 646 "inform7/Chapter 10/Excerpt Meanings.w"
;
break;
}
em->em_tokens[tc++] = array[i];
}
em->no_em_tokens = tc;
register_em(meaning_code, em);
return em;
}
#line 12 "inform7/Chapter 10/Unicode Translations.w"
sentence_handler TRANSLATESU_SH_handler =
{ SENTENCE_NT, TRANSLATESU_VB, 2, unicode_translates };
void unicode_translates(parse_node *pn) {
int nn1, nn2, as1, as2, cc;
as1 = pn->down->next->next->word_ref1; as2 = pn->down->next->next->word_ref2;
if (parse_nt_against_word_range(translates_into_unicode_sentence_object_NTM, as1, as2, NULL, NULL) == FALSE) return;
cc = most_recent_result;
if (Unicode_char_in_range(cc) == FALSE) return;
nn1 = pn->down->next->word_ref1; nn2 = pn->down->next->word_ref2;
parse_nt_against_word_range(translates_into_unicode_sentence_subject_NTM, nn1, nn2, NULL, NULL);
if ((most_recent_result != -1) && (most_recent_result != cc)) {
Problems__sentence_problem(_P_(C10UnicodeAlready),
"this Unicode character name has already been translated",
"so there must be some duplication somewhere.");
return;
}
Semantics__Nouns__ExcerptMeanings__register(
MISCELLANEOUS_MC, UNICODENAME_SMC, nn1, nn2,
STORE_POINTER_parse_node(Parser__Sentences__NPs__new_raw(as1, as2)));
}
#line 47 "inform7/Chapter 10/Unicode Translations.w"
int translates_into_unicode_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 50 "inform7/Chapter 10/Unicode Translations.w"
#line 57 "inform7/Chapter 10/Unicode Translations.w"
int translates_into_unicode_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 64 "inform7/Chapter 10/Unicode Translations.w"
Problems__sentence_problem(_P_(C10UnicodeNonLiteral),
"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 59 "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 60 "inform7/Chapter 10/Unicode Translations.w"
#line 80 "inform7/Chapter 10/Unicode Translations.w"
int unicode_character_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = R[1]; if (!(Unicode_char_in_range(R[1]))) return FALSE;;
#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 83 "inform7/Chapter 10/Unicode Translations.w"
int unicode_character_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 85 "inform7/Chapter 10/Unicode Translations.w"
meaning_list *ml = Parser__SP__parse_excerpt(MISCELLANEOUS_MC, w1, w2);
if ((ml) && (Semantics__Nouns__ExcerptMeanings__get_secondary_code(
Parser__SP__MeaningLists__meaning(ml)) == UNICODENAME_SMC)) {
parse_node *p = RETRIEVE_POINTER_parse_node(
Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
*X = Text__Vocabulary__get_literal_number_value(Text__word(p->word_ref1));
return TRUE;
}
return FALSE;
}
#line 99 "inform7/Chapter 10/Unicode Translations.w"
int Unicode_char_in_range(int cc) {
if ((cc < 0) || (cc >= 0x10000)) {
Problems__sentence_problem(_P_(C10UnicodeOutOfRange),
"Inform can only handle Unicode characters in the 16-bit range",
"from 0 to 65535.");
return FALSE;
}
return TRUE;
}
#line 61 "inform7/Chapter 11/Nametags.w"
individual_name *add_to_nametag_and_reg(nametag *t,
int w1, int w2, natural_language *foreign_language, int gender, int number, int options) {
individual_name *in = Text__Clusters__add(t->names, w1, w2, 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 = register_nametag(in->word_ref1, in->word_ref2, t, foreign_language);
Text__Clusters__set_principal_meaning(in, em);
}
return in;
}
#line 91 "inform7/Chapter 11/Nametags.w"
nametag *Data__Nametags__new(int w1, int w2, 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 = Text__Clusters__new();
if (options & PARSE_EXACTLY_NTOPT) t->match_exactly = TRUE;
if (w1 >= 0) {
add_to_nametag_and_reg(t, w1, w2, foreign_language, gender, 1, options);
}
if (options & ATTACH_TO_SEARCH_LIST_NTOPT)
{
#line 116 "inform7/Chapter 11/Nametags.w"
Parser__Sentences__Headings__disturb();
Parser__Sentences__Headings__attach_nametag(t);
Parser__Sentences__Headings__verify_divisions();
}
#line 108 "inform7/Chapter 11/Nametags.w"
;
return t;
}
#line 123 "inform7/Chapter 11/Nametags.w"
excerpt_meaning *register_nametag(int w1, int w2, nametag *t, natural_language *foreign_language) {
return Semantics__Nouns__ExcerptMeanings__register(
t->registration_category, 0, w1, w2, t->registration_to);
}
#line 131 "inform7/Chapter 11/Nametags.w"
void Data__Nametags__log(nametag *t) {
if (t == NULL) { LOG("<untagged>"); return; }
int w1 = -1, w2 = -1;
Data__Nametags__get_name(t, &w1, &w2, FALSE);
if (w1 >= 0) {
LOG("'");
if (w1 < 0) LOG("<nameless creator>");
else {
int i;
for (i=w1; i<=w2; i++) {
LOG("%s", Text__word_text(i));
if (i < w2) LOG(" ");
}
}
LOG("'");
}
}
#line 152 "inform7/Chapter 11/Nametags.w"
void Data__Nametags__get_name(nametag *t, int *w1, int *w2, int plural_flag) {
Text__Clusters__get_name(t->names, w1, w2, plural_flag);
}
void Data__Nametags__get_name_in_play(nametag *t, int *w1, int *w2, int plural_flag) {
Text__Clusters__get_name_in_play(t->names, w1, w2, plural_flag);
}
void Data__Nametags__set_plural_name(nametag *t, int pw1, int pw2) {
Text__Clusters__set_plural_name(t->names, pw1, pw2);
}
int Data__Nametags__full_name_includes(nametag *t, vocabulary_entry *wd) {
if (t == NULL) return FALSE;
int w1 = -1, w2 = -1;
Data__Nametags__get_name(t, &w1, &w2, FALSE);
if (w1 < 0) return FALSE;
int i;
for (i = w1; i <= w2; i++)
if (wd == Text__word(i)) return TRUE;
return FALSE;
}
#line 178 "inform7/Chapter 11/Nametags.w"
general_pointer Data__Nametags__tag_holder(nametag *t) {
if (t == NULL) return NULL_GENERAL_POINTER;
return t->tagged_to;
}
int Data__Nametags__priority(nametag *t) {
if (t == NULL) return 0;
return t->search_priority;
}
int Data__Nametags__range_number(nametag *t) {
if (t == NULL) return 0;
return t->range_number;
}
void Data__Nametags__set_range_number(nametag *t, int r) {
if (t == NULL) return;
t->range_number = r;
}
int Data__Nametags__exactitude(nametag *t) {
if (t == NULL) return FALSE;
if (use_exact_parsing_option) return TRUE;
return t->match_exactly;
}
excerpt_meaning *Data__Nametags__get_principal_meaning(nametag *t) {
return Text__Clusters__get_principal_meaning(t->names);
}
name_resolution_data *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 219 "inform7/Chapter 11/Nametags.w"
char *Data__Nametags__identifier(nametag *t) {
if (t == NULL) return "nothing";
return t->nt_I6_identifier;
}
void nametag_compose_identifier(nametag *t, char C, int N) {
int w1 = -1, w2 = -1;
Data__Nametags__get_name(t, &w1, &w2, FALSE);
char id[32];
if (w1 >= 0) {
Formats__Inform6__compose_identifier(id, C, N, w1, w2);
} else
sprintf(id, "X%d", N);
nametag_set_I6_representation(t, id);
}
void 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 249 "inform7/Chapter 11/Nametags.w"
void Data__Nametags__name_all(void) {
nametag *nt;
LOOP_OVER(nt, nametag)
nametag_compose_identifier(nt,
(nt->search_priority == KIND_PRIORITY)?'K':'I', nt->range_number);
parse_node *p;
TREE_LOOP(p)
if ((Parser__Nodes__type(p) == SENTENCE_NT) &&
(Parser__Nodes__int_annotation(p, category_of_I6_translation_ANNOT) == NAMETAG_I6TR))
{
#line 265 "inform7/Chapter 11/Nametags.w"
int w1 = p->down->next->word_ref1, w2 = p->down->next->word_ref2;
meaning_list *ml = Parser__SP__parse_excerpt(NAMETAG_MC, w1, w2-1);
if (ml) {
nametag *nt = Data__Nametags__disambiguate(ml, MAX_NAMETAG_PRIORITY);
if (nt) nametag_set_I6_representation(nt,
Text__word_text(p->down->next->next->word_ref1));
continue;
}
Problems__sentence_problem(_P_(C11BadObjectTranslation),
"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 259 "inform7/Chapter 11/Nametags.w"
;
}
#line 293 "inform7/Chapter 11/Nametags.w"
nametag *Data__Nametags__disambiguate(meaning_list *ml, int priority) {
int candidates = 0; nametag *first_nt = NULL;
for (meaning_list *ml2 = ml; ml2; ml2 = Parser__SP__MeaningLists__sideways(ml2)) {
nametag *nt = RETRIEVE_POINTER_nametag(
Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml2)));
if ((nt->search_priority >= 1) && (nt->search_priority <= priority)) {
first_nt = nt; candidates++;
}
}
if (candidates <= 1) return first_nt;
Parser__Sentences__Headings__construct_nametag_search_list();
nametag *nt;
LOOP_OVER(nt, nametag)
Parser__Sentences__Headings__set_nametag_search_score(nt, 0);
for (meaning_list *ml2 = ml; ml2; ml2 = Parser__SP__MeaningLists__sideways(ml2)) {
nametag *nt = RETRIEVE_POINTER_nametag(
Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml2)));
if ((nt->search_priority >= 1) && (nt->search_priority <= priority))
Parser__Sentences__Headings__set_nametag_search_score(nt,
Parser__SP__MeaningLists__match_score(ml2));
}
nametag *best_nt = Parser__Sentences__Headings__highest_scoring_nametag_searched();
if (best_nt) return best_nt;
return first_nt;
}
#line 326 "inform7/Chapter 11/Nametags.w"
sentence_handler TRANSLATESL_SH_handler =
{ SENTENCE_NT, TRANSLATESL_VB, 1, nl_translates };
#line 335 "inform7/Chapter 11/Nametags.w"
int translates_into_nl_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 11/Nametags.w"
#line 342 "inform7/Chapter 11/Nametags.w"
void nl_translates(parse_node *pn) {
int nn1, nn2, as1, as2;
as1 = pn->down->next->next->word_ref1; as2 = pn->down->next->next->word_ref2;
/* the object */
natural_language *nl = Parser__Nodes__get_defn_language(pn->down->next->next);
int g = Parser__Nodes__int_annotation(pn->down->next->next, gender_reference_ANNOT);
if (nl == NULL) internal_error("No such NL");
if (nl == English_language) {
Problems__sentence_problem(_P_(C11CantTranslateIntoEnglish),
"you can't translate into English",
"only out of it.");
return;
}
nn1 = pn->down->next->word_ref1; nn2 = pn->down->next->word_ref2;
if ((parse_nt_against_word_range(translates_into_nl_sentence_subject_NTM, nn1, nn2, NULL, NULL)) == FALSE) {
Problems__sentence_problem(_P_(C11CantTranslateValue),
"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 = Data__Instances__get_nametag(I);
if (t == NULL) internal_error("stuck on instance name");
add_to_nametag_and_reg(t, as1, as2, 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");
add_to_nametag_and_reg(t, as1, as2, nl, g,
1, REGISTER_SINGULAR_NTOPT + REGISTER_PLURAL_NTOPT);
break;
}
default:
internal_error("bad translation category");
}
}
#line 85 "inform7/Chapter 11/Instances.w"
instance *Data__Instances__new(int w1, int w2, kind *K) {
PROTECTED_MODEL_PROCEDURE;
{
#line 107 "inform7/Chapter 11/Instances.w"
if (K == NULL) K = K_object;
K = Kinds__weaken(K);
}
#line 87 "inform7/Chapter 11/Instances.w"
;
property *cp = Kinds__get_coinciding_property(K);
instance *I = CREATE(instance);
{
#line 113 "inform7/Chapter 11/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 = World__Subjects__new(Kinds__as_subject(K),
INST_SUB, STORE_POINTER_instance(I), CERTAIN_CE);
}
#line 90 "inform7/Chapter 11/Instances.w"
;
{
#line 139 "inform7/Chapter 11/Instances.w"
int exact_parsing = TRUE, any_parsing = TRUE;
if ((cp) && (Properties__Valued__Conditions__of_what(cp))) any_parsing = FALSE;
if (Kinds__le(K, K_object)) exact_parsing = FALSE;
if (any_parsing) {
if (exact_parsing)
I->tag = Data__Nametags__new(w1, w2,
STORE_POINTER_instance(I), INSTANCE_PRIORITY,
REGISTER_SINGULAR_NTOPT + PARSE_EXACTLY_NTOPT + ATTACH_TO_SEARCH_LIST_NTOPT,
NAMED_CONSTANT_MC, NULL, NEUTER_GENDER);
else
I->tag = Data__Nametags__new(w1, w2,
STORE_POINTER_instance(I), INSTANCE_PRIORITY,
REGISTER_SINGULAR_NTOPT + ATTACH_TO_SEARCH_LIST_NTOPT,
NAMETAG_MC, NULL, NEUTER_GENDER);
} else {
I->tag = Data__Nametags__new(w1, w2,
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 11/Instances.w"
;
{
#line 175 "inform7/Chapter 11/Instances.w"
if (!(Kinds__le(K, K_object))) {
if (Kinds__has_named_constant_values(K) == FALSE)
internal_error("tried to make an instance value for impossible kind");
I->enumeration_index = Kinds__new_enumerated_value(K);
if (cp) register_as_adjectival_constant(I, cp);
}
}
#line 92 "inform7/Chapter 11/Instances.w"
;
latest_instance = I;
LOGIF(OBJECT_CREATIONS, "Created instance: $O (kind $u)\n", I, K);
Config__Plugins__Call__new_named_instance_notify(I);
if ((Kinds__eq(K, K_grammatical_gender)) &&
(no_ggs_recorded < NO_GRAMMATICAL_GENDERS))
grammatical_genders[no_ggs_recorded++] = I;
return I;
}
#line 185 "inform7/Chapter 11/Instances.w"
parse_node *Data__Instances__get_creating_sentence(instance *I) {
if (I == NULL) return NULL;
return I->creating_sentence;
}
#line 193 "inform7/Chapter 11/Instances.w"
source_file *Data__Instances__get_creating_file(instance *I) {
if (I == NULL) return NULL;
return Text__file_of_origin(I->creating_sentence->word_ref1);
}
#line 207 "inform7/Chapter 11/Instances.w"
void Data__Instances__make_kind_coincident(kind *K, property *P) {
Kinds__set_coinciding_property(K, P);
Data__Instances__update_adjectival_forms(P);
}
#line 221 "inform7/Chapter 11/Instances.w"
void Data__Instances__update_adjectival_forms(property *P) {
if (Properties__is_either_or(P) == TRUE) return;
kind *K = Properties__Valued__kind(P);
if (P == Kinds__get_coinciding_property(K)) {
instance *I;
LOOP_OVER_INSTANCES(I, K)
register_as_adjectival_constant(I, P);
}
}
#line 238 "inform7/Chapter 11/Instances.w"
void 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);
World__Subjects__make_adj_const_domain(infs, I, P);
}
}
#line 249 "inform7/Chapter 11/Instances.w"
void Data__Instances__log(instance *I) {
if (I== NULL) { LOG("<null instance>"); return; }
if (logging_to_I6_text == FALSE) LOG("I%d", I->allocation_id);
Data__Nametags__log(I->tag);
if (!(Kinds__le(Data__Instances__kind(I), K_object)))
LOG("[$u]", Data__Instances__kind(I));
}
#line 263 "inform7/Chapter 11/Instances.w"
specification *Data__Instances__get_value(instance *I) {
specification *val = Specifications__Values__new_actual_CONSTANT(Data__Instances__kind(I));
ATTACH_TO_SPEC(val, instance, I);
Specifications__set_data(val, CONSTANT_ENUMERATION_SPDATA, I->enumeration_index);
int nw1, nw2;
Data__Instances__get_name(I, &nw1, &nw2, FALSE);
val->word_ref1 = nw1; val->word_ref2 = nw2;
return val;
}
int Data__Instances__get_numerical_value(instance *I) {
return I->enumeration_index;
}
inference_subject *Data__Instances__as_subject(instance *I) {
if (I == NULL) return NULL;
return I->as_subject;
}
#line 285 "inform7/Chapter 11/Instances.w"
void Data__Instances__get_name(instance *I, int *w1, int *w2, int plural) {
if ((I == NULL) || (I->tag == NULL)) { *w1 = -1; *w2 = -1; return; }
Data__Nametags__get_name(I->tag, w1, w2, plural);
}
void Data__Instances__get_name_in_play(instance *I, int *w1, int *w2, int plural) {
if ((I == NULL) || (I->tag == NULL)) { *w1 = -1; *w2 = -1; return; }
Data__Nametags__get_name_in_play(I->tag, w1, w2, plural);
}
int Data__Instances__full_name_includes(instance *I, vocabulary_entry *wd) {
if (I == NULL) return FALSE;
return Data__Nametags__full_name_includes(I->tag, wd);
}
nametag *Data__Instances__get_nametag(instance *I) {
return I->tag;
}
char *Data__Instances__identifier(instance *I) {
if (I == NULL) return "nothing";
return Data__Nametags__identifier(I->tag);
}
#line 312 "inform7/Chapter 11/Instances.w"
void Data__Instances__write_name_for_index(OUTPUT_STREAM, instance *I) {
int w1, w2;
Data__Instances__get_name(I, &w1, &w2, FALSE);
if (w1 >= 0) Text__print_raw_text_to_stream(w1, w2, OUT);
else {
WRITE("nameless ");
kind *K = Data__Instances__kind(I);
w1 = -1; w2 = -1;
Kinds__get_name(K, &w1, &w2, FALSE);
if (w1 >= 0) Text__print_raw_text_to_stream(w1, w2, OUT);
}
}
#line 333 "inform7/Chapter 11/Instances.w"
instance *Data__Instances__parse_object(int w1, int w2) {
meaning_list *ml;
if (w2<0) w2=w1; if (w1<0) return NULL;
if (parse_nt_against_word_range(literal_NTM, w1, w2, NULL, NULL)) return NULL;
ml = Parser__SP__parse_excerpt(NAMETAG_MC, w1, w2);
if (ml == NULL) return NULL;
nametag *nt = Data__Nametags__disambiguate(ml, MAX_NAMETAG_PRIORITY);
if (nt == NULL) return NULL;
if (Data__Nametags__priority(nt) != INSTANCE_PRIORITY) return NULL;
return RETRIEVE_POINTER_instance(Data__Nametags__tag_holder(nt));
}
#line 349 "inform7/Chapter 11/Instances.w"
int instance_of_object_NTMR(int w1, int w2, int *X, void **XP) {
#line 350 "inform7/Chapter 11/Instances.w"
instance *I = Data__Instances__parse_object(w1, w2);
if (I) { *XP = I; return TRUE; }
return FALSE;
}
int instance_of_non_object_NTMR(int w1, int w2, int *X, void **XP) {
#line 356 "inform7/Chapter 11/Instances.w"
meaning_list *ml = Parser__SP__parse_excerpt(NAMED_CONSTANT_MC, w1, w2);
if (ml == NULL) return FALSE;
*XP = RETRIEVE_POINTER_instance(
Semantics__Nouns__ExcerptMeanings__data(
Parser__SP__MeaningLists__meaning(ml)));
return TRUE;
}
int instance_NTMR(int w1, int w2, int *X, void **XP) {
#line 365 "inform7/Chapter 11/Instances.w"
if (parse_nt_against_word_range(literal_NTM, w1, w2, NULL, NULL)) return FALSE;
Text__Languages__remove_the(&w1, &w2);
instance *I = Data__Instances__parse_object(w1, w2);
if (I) { *XP = I; return TRUE; }
meaning_list *ml = Parser__SP__parse_excerpt(NAMED_CONSTANT_MC, w1, w2);
if (ml == NULL) return FALSE;
*XP = RETRIEVE_POINTER_instance(
Semantics__Nouns__ExcerptMeanings__data(
Parser__SP__MeaningLists__meaning(ml)));
return TRUE;
}
#line 391 "inform7/Chapter 11/Instances.w"
kind *Data__Instances__kind(instance *I) {
if (I == NULL) return NULL;
inference_subject *inherits_from = World__Subjects__narrowest_broader_subject(I->as_subject);
return World__Subjects__as_kind(inherits_from);
}
int Data__Instances__of_kind(instance *I, kind *match) {
if ((I == NULL) || (match == NULL)) return FALSE;
return Kinds__le(Data__Instances__kind(I), match);
}
#line 408 "inform7/Chapter 11/Instances.w"
void Data__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 = Data__Instances__kind(I);
int m = Kinds__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 432 "inform7/Chapter 11/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__handmade_problem(_P_(C11KindsIncompatible));
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__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 419 "inform7/Chapter 11/Instances.w"
;
return;
}
Config__Plugins__Call__set_kind_notify(I, new);
World__Subjects__falls_within(I->as_subject, Kinds__as_subject(new));
Parser__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 460 "inform7/Chapter 11/Instances.w"
parse_node *Data__Instances__get_kind_set_sentence(instance *I) {
return I->instance_of_set_at;
}
#line 480 "inform7/Chapter 11/Instances.w"
int Data__Instances__count(kind *K) {
int c = 0;
instance *I;
LOOP_OVER_INSTANCES(I, K) c++;
return c;
}
#line 499 "inform7/Chapter 11/Instances.w"
void Data__Instances__set_connection(instance *I, general_pointer gp) {
I->connection = gp;
}
general_pointer Data__Instances__get_connection(instance *I) {
return I->connection;
}
#line 511 "inform7/Chapter 11/Instances.w"
void Data__Nametags__increment_indexing_count(instance *I) {
I->index_appearances++;
}
int Data__Instances__indexed_yet(instance *I) {
if (I->index_appearances > 0) return TRUE;
return FALSE;
}
#line 523 "inform7/Chapter 11/Instances.w"
void Data__Instances__index_name(instance *I) {
int w1 = -1, w2 = -1;
Data__Instances__get_name_in_play(I, &w1, &w2, FALSE);
if (w1 >= 0) {
Text__print_raw_text_to_stream(w1, w2, ifl);
return;
}
kind *K = Data__Instances__kind(I);
Kinds__get_name_in_play(K, &w1, &w2, FALSE);
if (w1 >= 0) {
Text__print_raw_text_to_stream(w1, w2, ifl);
return;
}
INDEX("nameless");
}
#line 542 "inform7/Chapter 11/Instances.w"
void Data__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 Data__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 = Text__file_of_origin(at->word_ref1);
if (sf == primary_source_file) {
k++;
if (k == 1) {
Formats__HTML__open_para(ifl, 1, "tight");
INDEX("<i>mentioned in rules:</i> ");
} else INDEX("; ");
Index__link(at->word_ref1);
}
}
}
if (k > 0) INDEX("</p>");
}
#line 582 "inform7/Chapter 11/Instances.w"
void Data__Instances__Subjects__get_name_text(inference_subject *from, int *w1, int *w2) {
instance *I = World__Subjects__as_nc(from);
Data__Instances__get_name(I, w1, w2, FALSE);
}
general_pointer Data__Instances__Subjects__new_permission_granted(inference_subject *from) {
return STORE_POINTER_property_of_value_storage(
Properties__Implementation__OfValues__get_storage());
}
void Data__Instances__Subjects__complete_model(inference_subject *infs) {
}
void Data__Instances__Subjects__check_model(inference_subject *infs) {
}
#line 601 "inform7/Chapter 11/Instances.w"
void Data__Instances__Subjects__make_adj_const_domain(inference_subject *S,
instance *I, property *P) {
Data__Instances__make_adj_const_domain(I, P, NULL, World__Subjects__as_instance(S));
}
#line 610 "inform7/Chapter 11/Instances.w"
void Data__Instances__Subjects__write_element_of_condition(inference_subject *infs, char *cond) {
instance *I = World__Subjects__as_nc(infs);
sprintf(cond, "t_0 == %s", Data__Instances__identifier(I));
}
#line 623 "inform7/Chapter 11/Instances.w"
int Data__Instances__Subjects__compile_all(OUTPUT_STREAM) {
Properties__Implementation__OfObjects__compile_all(OUT);
instance *I;
LOOP_OVER(I, instance)
if (Kinds__le(Data__Instances__kind(I), K_object) == FALSE)
Data__Instances__Subjects__compile(OUT, Data__Instances__as_subject(I));
return TRUE;
}
#line 635 "inform7/Chapter 11/Instances.w"
void Data__Instances__Subjects__compile(OUTPUT_STREAM, inference_subject *infs) {
instance *I = World__Subjects__as_nc(infs);
if (Kinds__le(Data__Instances__kind(I), K_object))
Properties__Implementation__OfObjects__compile_subject(OUT, infs);
else
WRITE("Constant %s = %d;\n", Data__Instances__identifier(I),
I->enumeration_index);
}
#line 658 "inform7/Chapter 11/Instances.w"
adjectival_phrase *Data__Instances__get_adjectival_phrase(instance *I) {
return I->usage_as_aph;
}
adjective_meaning *Data__Instances__Adjectives__parse(parse_node *pn, int sense,
int adj_name_w1, int adj_name_w2, int dom_name_w1, int dom_name_w2,
int cond_w1, int cond_w2, int called_w1, int called_w2) {
return NULL;
}
void Data__Instances__Adjectives__compiling_soon(adjective_meaning *am, instance *I, int T) {
}
int Data__Instances__Adjectives__compile(instance *I, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
#line 681 "inform7/Chapter 11/Instances.w"
int Data__Instances__Adjectives__assert(instance *I,
inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) {
if (parity == FALSE) return FALSE;
property *P = Kinds__get_coinciding_property(Data__Instances__kind(I));
if (P == NULL) internal_error("enumerative adjective on non-property");
World__Inferences__draw_property(infs_to_assert_on, P, Data__Instances__get_value(I));
return TRUE;
}
#line 693 "inform7/Chapter 11/Instances.w"
int Data__Instances__Adjectives__index(instance *I) {
property *P = Kinds__get_coinciding_property(Data__Instances__kind(I));
if (Properties__Valued__Conditions__of_what(P) == NULL) {
if (Properties__permission_list(P)) {
INDEX("(of "); World__Permissions__index(P); INDEX(") ");
}
INDEX("having this ");
Text__print_raw_text_to_stream(P->word_ref1, P->word_ref2, ifl);
} else {
INDEX("a condition which is otherwise ");
kind *K = Data__Instances__kind(I);
int no_alts = Data__Instances__count(K) - 1, i = 0;
instance *alt;
LOOP_OVER_INSTANCES(alt, K)
if (alt != I) {
INDEX("</i>");
int nw1, nw2;
Data__Instances__get_name(alt, &nw1, &nw2, FALSE);
Text__print_raw_text_to_stream(nw1, nw2, ifl);
INDEX("<i>");
i++;
if (i == no_alts-1) INDEX(" or ");
else if (i < no_alts) INDEX(", ");
}
}
return TRUE;
}
#line 734 "inform7/Chapter 11/Instances.w"
void Data__Instances__make_adj_const_domain(instance *I, property *P,
kind *set, instance *singleton) {
kind *D = NULL;
{
#line 746 "inform7/Chapter 11/Instances.w"
if (singleton) D = Data__Instances__kind(singleton);
else if (set) D = set;
if (D == NULL) internal_error("No adjectival constant domain");
}
#line 737 "inform7/Chapter 11/Instances.w"
;
adjective_meaning *am = NULL;
{
#line 753 "inform7/Chapter 11/Instances.w"
int nw1, nw2;
Data__Instances__get_name(I, &nw1, &nw2, FALSE);
am = Semantics__Adjectives__Meanings__new(ENUMERATIVE_KADJ,
STORE_POINTER_instance(I), nw1, nw2);
I->usage_as_aph = Semantics__Adjectives__Meanings__declare(am, nw1, nw2);
if (singleton) Semantics__Adjectives__Meanings__set_domain_from_instance(am, singleton);
else if (set) Semantics__Adjectives__Meanings__set_domain_from_kind(am, set);
}
#line 739 "inform7/Chapter 11/Instances.w"
;
{
#line 764 "inform7/Chapter 11/Instances.w"
i6_schema *sch = Semantics__Adjectives__Meanings__set_i6_schema(am,
TEST_ADJECTIVE_TASK, FALSE);
Code__Schemas__modify(sch,
"GProperty(%k, *1, %s) == %d",
D, Properties__get_translation(P), I->enumeration_index);
sch = Semantics__Adjectives__Meanings__set_i6_schema(am,
NOW_ADJECTIVE_TRUE_TASK, FALSE);
Code__Schemas__modify(sch,
"WriteGProperty(%k, *1, %s, %d)",
D, Properties__get_translation(P), I->enumeration_index);
}
#line 740 "inform7/Chapter 11/Instances.w"
;
}
#line 18 "inform7/Chapter 11/Index Physical World.w"
void Data__Objects__page_Kinds(void) {
{
#line 29 "inform7/Chapter 11/Index Physical World.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__lt(K, K_object)) {
int w1, w2;
Kinds__get_name(K, &w1, &w2, FALSE);
if (w1 >= 0) {
char temp[MAX_WORD_LENGTH + 10];
sprintf(temp, "kind_%s", Text__word_text(w1));
char *ref = Index__DocReferences__validate_if_possible(temp);
if (ref) Kinds__set_documentation_reference(K, ref);
}
}
}
#line 19 "inform7/Chapter 11/Index Physical World.w"
;
Kinds__Index__index_kinds(1);
}
#line 48 "inform7/Chapter 11/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 */
Plugins__Map__establish_benchmark_room();
Plugins__Map__traverse_for_map_parameters(1);
Plugins__Map__establish_spatial_coordinates();
Plugins__Map__render_map_as_HTML();
Plugins__Map__add_region_key();
Plugins__Map__render_map_as_EPS();
Plugins__Backdrops__index_object_further(NULL, 0, FALSE,
"<p><b>Present everywhere:</b><br>", "<p><hr><p>");
Index__anchor("MDETAILS");
int unruly = FALSE;
{
#line 73 "inform7/Chapter 11/Index Physical World.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Plugins__Spatial__no_detail_index(I))
|| (Plugins__Map__object_is_a_direction(I)))
Data__Nametags__increment_indexing_count(I);
}
#line 64 "inform7/Chapter 11/Index Physical World.w"
;
{
#line 82 "inform7/Chapter 11/Index Physical World.w"
instance *reg;
LOOP_OVER_OBJECT_INSTANCES(reg)
if (Plugins__Regions__object_is_a_region(reg)) {
int subheaded = FALSE;
Data__Nametags__increment_indexing_count(reg);
instance *rm;
LOOP_OVER_OBJECT_INSTANCES(rm)
if ((Plugins__Spatial__object_is_a_room(rm)) &&
(Plugins__Regions__enclosing(rm) == reg)) {
if (subheaded == FALSE) {
{
#line 155 "inform7/Chapter 11/Index Physical World.w"
if ((unruly) && (suppress_panel_changes == FALSE)) INDEX("<p><hr><p>");
unruly = TRUE;
}
#line 92 "inform7/Chapter 11/Index Physical World.w"
;
{
#line 106 "inform7/Chapter 11/Index Physical World.w"
INDEX("<b>The <i>");
int w1, w2;
Data__Instances__get_name(reg, &w1, &w2, FALSE);
Text__print_raw_text_to_stream(w1, w2, ifl);
INDEX("</i> region");
instance *within = Plugins__Regions__enclosing(reg);
if (within) {
INDEX(" within the <i>");
int w1, w2;
Data__Instances__get_name(within, &w1, &w2, FALSE);
Text__print_raw_text_to_stream(w1, w2, ifl);
INDEX("</i> region");
}
INDEX("</b>");
}
#line 93 "inform7/Chapter 11/Index Physical World.w"
;
Plugins__Backdrops__index_object_further(reg, 0, FALSE, "<br>", "");
INDEX("<p>");
subheaded = TRUE;
}
Plugins__Map__render_single_room_as_HTML(rm);
Data__Nametags__increment_indexing_count(rm);
}
}
}
#line 65 "inform7/Chapter 11/Index Physical World.w"
;
{
#line 124 "inform7/Chapter 11/Index Physical World.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Plugins__Spatial__object_is_a_room(I)) &&
(Data__Instances__indexed_yet(I) == FALSE)) {
{
#line 155 "inform7/Chapter 11/Index Physical World.w"
if ((unruly) && (suppress_panel_changes == FALSE)) INDEX("<p><hr><p>");
unruly = TRUE;
}
#line 128 "inform7/Chapter 11/Index Physical World.w"
;
Plugins__Map__render_single_room_as_HTML(I);
}
}
#line 66 "inform7/Chapter 11/Index Physical World.w"
;
{
#line 138 "inform7/Chapter 11/Index Physical World.w"
int out_of_play_count = 0;
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Data__Instances__indexed_yet(I) == FALSE) &&
(Plugins__Spatial__progenitor(I) == NULL)) {
{
#line 155 "inform7/Chapter 11/Index Physical World.w"
if ((unruly) && (suppress_panel_changes == FALSE)) INDEX("<p><hr><p>");
unruly = TRUE;
}
#line 143 "inform7/Chapter 11/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 67 "inform7/Chapter 11/Index Physical World.w"
;
}
#line 169 "inform7/Chapter 11/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 */
Data__Nametags__increment_indexing_count(I);
if (Data__Instances__of_kind(I, K_room)) indexing_room = I;
nt = Data__Instances__get_nametag(I);
}
if (K) nt = Kinds__get_nametag(K);
if (nt == NULL) internal_error("no nametag to index");
int shaded = FALSE;
{
#line 208 "inform7/Chapter 11/Index Physical World.w"
if (tabulating_kinds_index) Kinds__Index__begin_chart_row();
if (details) {
Formats__HTML__open_para(ifl, depth, "halftight");
if ((K) || (I != indexing_room)) Index__anchor(Data__Nametags__identifier(nt));
} else {
Formats__HTML__open_para(ifl, depth, "tight");
if (I) Plugins__Spatial__index_spatial_relationship(I);
}
}
#line 185 "inform7/Chapter 11/Index Physical World.w"
;
int xtra = -1;
if (I) xtra = xtras_count++;
if (xtra >= 0) Index__extra_link(xtra);
{
#line 229 "inform7/Chapter 11/Index Physical World.w"
if (tabulating_kinds_index) {
int c = Data__Instances__count(K);
if ((c == 0) && (details == FALSE)) shaded = TRUE;
if (shaded) INDEX("<font color=\"%s\">", KINDS_INDEX_SHADE);
{
#line 243 "inform7/Chapter 11/Index Physical World.w"
int w1, w2;
Data__Nametags__get_name_in_play(nt, &w1, &w2, FALSE);
if ((w1 < 0) && (I)) {
kind *IK = Data__Instances__kind(I);
Kinds__get_name_in_play(IK, &w1, &w2, FALSE);
}
if (w1 < 0) {
INDEX("nameless");
} else {
if ((details) || (Plugins__Spatial__object_is_a_room(I))) INDEX("<b>");
Text__print_raw_text_to_stream(w1, w2, ifl);
if ((details) || (Plugins__Spatial__object_is_a_room(I))) INDEX("</b>");
if (details)
{
#line 261 "inform7/Chapter 11/Index Physical World.w"
if (I) {
kind *k = Data__Instances__kind(I);
if (Kinds__lt(k, K_object)) {
int w1 = -1, w2 = -1;
Kinds__get_name_in_play(k, &w1, &w2, FALSE);
if (w1 >= 0) {
INDEX(", a kind of ");
Text__print_raw_text_to_stream(w1, w2, ifl);
}
}
}
int pw1, pw2;
Data__Nametags__get_name_in_play(nt, &pw1, &pw2, TRUE);
if (pw1 >= 0) {
INDEX(" (<i>plural</i> ");
Text__print_raw_text_to_stream(pw1, pw2, ifl);
INDEX(")");
}
}
#line 255 "inform7/Chapter 11/Index Physical World.w"
;
}
}
#line 233 "inform7/Chapter 11/Index Physical World.w"
;
if (shaded) INDEX("</font>");
if ((details == FALSE) && (c > 0)) INDEX(" [%d]", c);
} else {
{
#line 243 "inform7/Chapter 11/Index Physical World.w"
int w1, w2;
Data__Nametags__get_name_in_play(nt, &w1, &w2, FALSE);
if ((w1 < 0) && (I)) {
kind *IK = Data__Instances__kind(I);
Kinds__get_name_in_play(IK, &w1, &w2, FALSE);
}
if (w1 < 0) {
INDEX("nameless");
} else {
if ((details) || (Plugins__Spatial__object_is_a_room(I))) INDEX("<b>");
Text__print_raw_text_to_stream(w1, w2, ifl);
if ((details) || (Plugins__Spatial__object_is_a_room(I))) INDEX("</b>");
if (details)
{
#line 261 "inform7/Chapter 11/Index Physical World.w"
if (I) {
kind *k = Data__Instances__kind(I);
if (Kinds__lt(k, K_object)) {
int w1 = -1, w2 = -1;
Kinds__get_name_in_play(k, &w1, &w2, FALSE);
if (w1 >= 0) {
INDEX(", a kind of ");
Text__print_raw_text_to_stream(w1, w2, ifl);
}
}
}
int pw1, pw2;
Data__Nametags__get_name_in_play(nt, &pw1, &pw2, TRUE);
if (pw1 >= 0) {
INDEX(" (<i>plural</i> ");
Text__print_raw_text_to_stream(pw1, pw2, ifl);
INDEX(")");
}
}
#line 255 "inform7/Chapter 11/Index Physical World.w"
;
}
}
#line 237 "inform7/Chapter 11/Index Physical World.w"
;
}
}
#line 189 "inform7/Chapter 11/Index Physical World.w"
;
if (I)
{
#line 283 "inform7/Chapter 11/Index Physical World.w"
if (Config__Plugins__Call__annotate_in_World_index(I) == FALSE) {
kind *k = Data__Instances__kind(I);
int w1 = -1, w2 = -1;
if (k) Kinds__get_name(k, &w1, &w2, FALSE);
if ((k) && (w1 >= 0) &&
(Kinds__eq(k, K_object) == FALSE) &&
(Kinds__eq(k, K_thing) == FALSE) &&
(Kinds__eq(k, K_room) == FALSE)) {
INDEX(" - <i>");
Text__print_raw_text_to_stream(w1, w2, ifl);
INDEX("</i>");
}
}
}
#line 190 "inform7/Chapter 11/Index Physical World.w"
;
{
#line 301 "inform7/Chapter 11/Index Physical World.w"
parse_node *C = NULL;
if (K) C = Kinds__get_creating_sentence(K);
if (I) C = Data__Instances__get_creating_sentence(I);
if (C) Index__link(C->word_ref1);
if ((K) && (Kinds__get_documentation_reference(K)))
Index__doc_link(Kinds__get_documentation_reference(K));
if ((details == FALSE) && (K))
Index__below_link(Data__Nametags__identifier(nt));
}
#line 191 "inform7/Chapter 11/Index Physical World.w"
;
{
#line 220 "inform7/Chapter 11/Index Physical World.w"
if (tabulating_kinds_index)
Kinds__Index__end_chart_row(shaded, K, "tick", "tick", "tick");
else {
INDEX("</p>\n");
}
}
#line 192 "inform7/Chapter 11/Index Physical World.w"
;
if (details)
{
#line 325 "inform7/Chapter 11/Index Physical World.w"
Formats__HTML__open_para(ifl, depth, "tight");
if (I) World__Inferences__index(Data__Instances__as_subject(I), TRUE);
else World__Inferences__index(Kinds__as_subject(K), TRUE);
if (K) {
INDEX("</p>");
Data__Objects__index_instances(K, depth);
}
}
#line 193 "inform7/Chapter 11/Index Physical World.w"
;
if (xtra >= 0) {
Index__extra_div_open(xtra, depth+1, "e0e0e0");
{
#line 336 "inform7/Chapter 11/Index Physical World.w"
Formats__HTML__open_para(ifl, 1, "tight");
kind *IK = Data__Instances__kind(I);
int i = 0;
while ((IK != K_object) && (IK)) {
i++;
IK = Kinds__super(IK);
}
int j;
for (j=i-1; j>=0; j--) {
int k; IK = Data__Instances__kind(I);
for (k=0; k<j; k++) IK = Kinds__super(IK);
if (j != i-1) INDEX(" &gt; ");
int w1 = -1, w2 = -1;
Kinds__get_name(IK, &w1, &w2, FALSE);
Text__print_raw_text_to_stream(w1, w2, ifl);
}
parse_node *P = Data__Instances__get_kind_set_sentence(I);
if (P) Index__link(P->word_ref1);
INDEX(" &gt; <b>");
Data__Instances__index_name(I);
INDEX("</b></p>");
}
#line 196 "inform7/Chapter 11/Index Physical World.w"
;
{
#line 361 "inform7/Chapter 11/Index Physical World.w"
World__Inferences__index_specific(Data__Instances__as_subject(I));
}
#line 197 "inform7/Chapter 11/Index Physical World.w"
;
Config__Plugins__Call__add_to_World_index(I);
Data__Instances__index_usages(I);
Index__extra_div_close("e0e0e0");
}
{
#line 313 "inform7/Chapter 11/Index Physical World.w"
if (K) {
kind *K2;
LOOP_OVER_BASE_KINDS(K2)
if (Kinds__eq(Kinds__super(K2), K))
Data__Objects__index(NULL, K2, depth+1, details);
} else {
Plugins__Spatial__index_object_further(I, depth, details);
}
}
#line 202 "inform7/Chapter 11/Index Physical World.w"
;
}
#line 366 "inform7/Chapter 11/Index Physical World.w"
void Data__Objects__index_instances(kind *K, int depth) {
Formats__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);
int p1 = -1, p2 = -1;
Kinds__get_name(K, &p1, &p2, TRUE);
if (p1 >= 0) Text__print_raw_text_to_stream(p1, p2, ifl);
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\">");
Data__Instances__index_name(I);
INDEX("</font>");
parse_node *at = Data__Instances__get_creating_sentence(I);
if (at) Index__link(at->word_ref1);
}
Index__extra_div_close("e0e0e0");
} else {
c = 0;
LOOP_OVER_INSTANCES(I, K) {
if (c > 0) INDEX(", "); c++;
INDEX("<font color=\"#808080\">");
Data__Instances__index_name(I);
INDEX("</font>");
parse_node *at = Data__Instances__get_creating_sentence(I);
if (at) Index__link(at->word_ref1);
}
INDEX("</p>");
}
}
#line 26 "inform7/Chapter 12/Architecture of the S-Parser.w"
int s_plain_text_NTMR(int w1, int w2, int *X, void **XP) {
#line 27 "inform7/Chapter 12/Architecture of the S-Parser.w"
*XP = ML_PLAIN(w1, w2);
return TRUE;
}
#line 49 "inform7/Chapter 12/Architecture of the S-Parser.w"
int s_plain_text_with_equals_NTMR(int w1, int w2, int *X, void **XP) {
#line 50 "inform7/Chapter 12/Architecture of the S-Parser.w"
int i, j;
for (i=w1; i<=w2; i++) {
char *p = Text__word_raw_text(i);
for (j=0; p[j]; j++)
if (p[j] == '=') {
*XP = ML_PLAIN(w1, w2);
return TRUE;
}
}
return FALSE;
}
#line 223 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__log_production(unsigned int production) {
if (production == 0) { LOG("<null-production>"); return; }
if (production & 0x80000000) {
switch (production) {
case ABSENT_SUBJECT_ML: LOG("ABSENT_SUBJECT_ML"); break;
case ACTION_ML: LOG("ACTION_ML"); break;
case ADVERB_ML: LOG("ADVERB_ML"); break;
case AL_ML: LOG("AL_ML"); break;
case AP_ML: LOG("AP_ML"); break;
case CALLED_ML: LOG("CALLED_ML"); break;
case CARRIED_ML: LOG("CARRIED_ML"); break;
case CASE_ML: LOG("CASE_ML"); break;
case OTHERWISE_ML: LOG("OTHERWISE_ML"); break;
case CMD_ML: LOG("CMD_ML"); break;
case COMPOSITED_ML: LOG("COMPOSITED_ML"); break;
case COND_AND_ML: LOG("COND_AND_ML"); break;
case COND_NOT_ML: LOG("COND_NOT_ML"); break;
case COND_OR_ML: LOG("COND_OR_ML"); break;
case COND_PAST_ML: LOG("COND_PAST_ML"); break;
case COND_PHRASE_ML: LOG("COND_PHRASE_ML"); break;
case COND_ML: LOG("COND_ML"); break;
case DC_ADJS_ML: LOG("DC_ADJS_ML"); break;
case DC_ADJSNOUN_ML: LOG("DC_ADJSNOUN_ML"); break;
case DC_NOUN_ML: LOG("DC_NOUN_ML"); break;
case DC_ML: LOG("DC_ML"); break;
case DETERMINER_ML: LOG("DETERMINER_ML"); break;
case EQUATION_INLINE_ML: LOG("EQUATION_INLINE_ML"); break;
case EQUATION_WHERE_ML: LOG("EQUATION_WHERE_ML"); break;
case INSTEAD_ML: LOG("INSTEAD_ML"); break;
case LITERAL_ML: LOG("LITERAL_ML"); break;
case LOCAL_ML: LOG("LOCAL_ML"); break;
case MEMBER_OF_ML: LOG("MEMBER_OF_ML"); break;
case ADJ_NOT_ML: LOG("ADJ_NOT_ML"); break;
case NP_ML: LOG("NP_ML"); break;
case OPTION_ML: LOG("OPTION_ML"); break;
case PHR_OPT_ML: LOG("PHR_OPT_ML"); break;
case PHRASE_ML: LOG("PHRASE_ML"); break;
case PREP_ML: LOG("PREP_ML"); break;
case SAY_ML: LOG("SAY_ML"); break;
case SAY_ADJECTIVE_ML: LOG("SAY_ADJECTIVE_ML"); break;
case SAY_VERB_ML: LOG("SAY_VERB_ML"); break;
case SAY_MODAL_VERB_ML: LOG("SAY_MODAL_VERB_ML"); break;
case SN_ML: LOG("SN_ML"); break;
case STV_ML: LOG("STV_ML"); break;
case SV_ML: LOG("SV_ML"); break;
case TE_CALLED_ML: LOG("TE_CALLED_ML"); break;
case TE_EX_VAR_ML: LOG("TE_EX_VAR_ML"); break;
case TE_GL_VAR_ML: LOG("TE_GL_VAR_ML"); break;
case TE_NEW_VAR_ML: LOG("TE_NEW_VAR_ML"); break;
case TE_ML: LOG("TE_ML"); break;
case TE_VAR_ML: LOG("TE_VAR_ML"); break;
case THERE_ML: LOG("THERE_ML"); break;
case TIME_ML: LOG("TIME_ML"); break;
case TR_CORR_ML: LOG("TR_CORR_ML"); break;
case TR_ENTRY_ML: LOG("TR_ENTRY_ML"); break;
case TR_IN_ROW_ML: LOG("TR_IN_ROW_ML"); break;
case TR_LISTED_IN_ML: LOG("TR_LISTED_IN_ML"); break;
case TR_OF_IN_ML: LOG("TR_OF_IN_ML"); break;
case TR_ML: LOG("TR_ML"); break;
case TYPE_ML: LOG("TYPE_ML"); break;
case UNPARSED_ML: LOG("UNPARSED_ML"); break;
case VAL_LIST_ENTRY_ML: LOG("VAL_LIST_ENTRY_ML"); break;
case VAL_NOTHING_ML: LOG("VAL_NOTHING_ML"); break;
case VAL_PAIR_ML: LOG("VAL_PAIR_ML"); break;
case VAL_ML: LOG("VAL_ML"); break;
case VAL_PROP_OF_ML: LOG("VAL_PROP_OF_ML"); break;
case VAL_RESPONSE_ML: LOG("VAL_RESPONSE_ML"); break;
case VALUE_PHRASE_ML: LOG("VALUE_PHRASE_ML"); break;
case VERB_ML: LOG("VERB_ML"); break;
case VP_ML: LOG("VP_ML"); break;
default: LOG("<unknown-production-%08x>", production); break;
}
} else Semantics__Nouns__ExcerptMeanings__log_meaning_code(production);
}
#line 305 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__log(meaning_list *ml) {
if (ml == NULL) { LOG("<null-meaning-list>\n"); return; }
log_ml_recursively(ml, 0, 0, 1);
}
void log_ml_recursively(meaning_list *ml, int num, int of, int gen) {
if (gen > LOG_ML_SAFETY_LIMIT) { LOG("*** Pruned: tree large or damaged ***\n"); return; }
int w1, w2;
{
#line 346 "inform7/Chapter 12/Meaning Lists.w"
if (num == 0) {
meaning_list *ml2;
for (ml2 = ml, of = 0; ml2; ml2 = ml2->next_alternative, of++) ;
num = 1;
}
}
#line 313 "inform7/Chapter 12/Meaning Lists.w"
;
if (ml == NULL) { LOG("NULL\n"); return; }
if (of > 1) {
LOG("[%d/%d] ", num, of);
if (ml->score != 0) LOG("(score %d) ", ml->score);
}
if (ml->em) LOG("$M", ml->em);
else Parser__SP__MeaningLists__log_production(ml->production);
if (ml->type_spec) {
LOG(" => ");
if (ml->production == TIME_ML) LOG("$t", Specifications__get_condition_tense(ml->type_spec));
else LOG("$S", ml->type_spec);
}
{
#line 359 "inform7/Chapter 12/Meaning Lists.w"
switch (ml->production) {
case DETERMINER_ML:
LOG(" => ");
Semantics__Quantifiers__log(RETRIEVE_POINTER_quantifier(ml->data_attached), ml->score); break;
case VERB_ML:
LOG(" => ");
Semantics__VerbUsage__log(RETRIEVE_POINTER_verb_usage(ml->data_attached)); break;
case PREP_ML:
LOG(" => ");
Semantics__PrepositionUsage__log(RETRIEVE_POINTER_preposition_usage(ml->data_attached)); break;
}
}
#line 327 "inform7/Chapter 12/Meaning Lists.w"
;
Parser__SP__MeaningLists__get_text(ml, &w1, &w2);
if (w1 >= 0) LOG(" / \"$W\"", w1, w2);
LOG("\n");
if (ml->child) {
LOG_INDENT; log_ml_recursively(ml->child, 0, 0, gen+1); LOG_OUTDENT;
}
if (ml->next_alternative) log_ml_recursively(ml->next_alternative, num+1, of, gen+1);
if (ml->sibling) log_ml_recursively(ml->sibling, 0, 0, gen+1);
}
#line 447 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *LP_marker = NULL, *GAP_marker = NULL, *TAIL_marker = NULL;
meaning_list *earliest_ephemeral_ML_today = NULL;
int current_creation_time = 0, max_ML_creations_per_day = 0, no_ML_creations_today;
#line 455 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *get_available_ml(int seeking_permanent_slot) {
meaning_list *new;
if ((seeking_permanent_slot) && (GAP_marker)) {
new = GAP_marker;
LOGIF(MEANING_LIST_ALLOCATION, "Time %d: Using GAP position ML%d with expiry time %d\n",
current_creation_time, new->allocation_id, new->expiry_time);
/* here TAIL does not change */
{
#line 500 "inform7/Chapter 12/Meaning Lists.w"
do {
GAP_marker = NEXT_OBJECT(GAP_marker, meaning_list);
GAP_movements++;
} while ((GAP_marker) && (GAP_marker->expiry_time >= current_creation_time));
if (GAP_marker == TAIL_marker) GAP_marker = NULL;
}
#line 462 "inform7/Chapter 12/Meaning Lists.w"
;
} else if (TAIL_marker) {
new = TAIL_marker;
LOGIF(MEANING_LIST_ALLOCATION, "Time %d: Using TAIL position ML%d with expiry time %d\n",
current_creation_time, new->allocation_id, new->expiry_time);
/* here any GAP is unaltered */
TAIL_marker = NEXT_OBJECT(TAIL_marker, meaning_list);
if (seeking_permanent_slot) LP_marker = new;
} else {
new = CREATE(meaning_list);
LOGIF(MEANING_LIST_ALLOCATION, "Time %d: Using new position ML%d\n",
current_creation_time, new->allocation_id);
/* here any TAIL vanishes, but a GAP is unaltered */
TAIL_marker = NULL;
if (seeking_permanent_slot) LP_marker = new;
}
if (seeking_permanent_slot) new->expiry_time = THE_INFINITE_FUTURE;
else {
new->expiry_time = current_creation_time;
if (earliest_ephemeral_ML_today == NULL) earliest_ephemeral_ML_today = new;
}
no_ML_creations_today++;
LOGIF(MEANING_LIST_ALLOCATION, "Time %d: GAP = ML%d, LP = ML%d, TAIL = ML%d\n",
current_creation_time,
(GAP_marker)?(GAP_marker->allocation_id):0,
(LP_marker)?(LP_marker->allocation_id):0,
(TAIL_marker)?(TAIL_marker->allocation_id):0);
return new;
}
#line 511 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__finish_this_session(void) {
if (current_creation_time < THE_INFINITE_FUTURE) {
if (Log__Aspects__on(MEANING_LIST_ALLOCATION_DA)) {
LOG("Time %d: %d items were created today ",
current_creation_time, no_ML_creations_today);
if (no_ML_creations_today > max_ML_creations_per_day) {
LOG("- a new record!");
max_ML_creations_per_day = no_ML_creations_today;
}
LOG("\n");
}
{
#line 556 "inform7/Chapter 12/Meaning Lists.w"
TAIL_marker = NEXT_OBJECT(LP_marker, meaning_list);
if (GAP_marker == NULL) {
GAP_marker = earliest_ephemeral_ML_today;
if ((TAIL_marker) && (GAP_marker) &&
(GAP_marker->allocation_id >= TAIL_marker->allocation_id))
GAP_marker = NULL;
}
}
#line 522 "inform7/Chapter 12/Meaning Lists.w"
;
current_creation_time++;
earliest_ephemeral_ML_today = NULL;
no_ML_creations_today = 0;
}
}
#line 619 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__new(unsigned int code_number) {
meaning_list *ml = get_available_ml(FALSE);
{
#line 636 "inform7/Chapter 12/Meaning Lists.w"
ml->em = NULL;
ml->next_alternative = NULL;
ml->sibling = NULL;
ml->child = NULL;
ml->type_spec = NULL;
ml->score = 0;
ml->production = code_number;
Parser__SP__MeaningLists__set_text(ml, -1, -1);
ml->data_attached = NULL_GENERAL_POINTER;
}
#line 621 "inform7/Chapter 12/Meaning Lists.w"
;
no_ephemeral_MLs++;
return ml;
}
meaning_list *Parser__SP__MeaningLists__new_permanent(unsigned int code_number) {
meaning_list *ml = get_available_ml(TRUE);
{
#line 636 "inform7/Chapter 12/Meaning Lists.w"
ml->em = NULL;
ml->next_alternative = NULL;
ml->sibling = NULL;
ml->child = NULL;
ml->type_spec = NULL;
ml->score = 0;
ml->production = code_number;
Parser__SP__MeaningLists__set_text(ml, -1, -1);
ml->data_attached = NULL_GENERAL_POINTER;
}
#line 628 "inform7/Chapter 12/Meaning Lists.w"
;
no_permanent_MLs++;
return ml;
}
#line 650 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__new_with_words(unsigned int code_number, int w1, int w2) {
meaning_list *ml = Parser__SP__MeaningLists__new(code_number);
Parser__SP__MeaningLists__set_text(ml, w1, w2);
return ml;
}
#line 659 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__from_nametag(nametag *nt) {
meaning_list *ml = Parser__SP__MeaningLists__new(NAMETAG_MC);
ml->em = Data__Nametags__get_principal_meaning(nt);
ml->score = 1;
return ml;
}
#line 672 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__type_from_ID(int ID_number) {
meaning_list *ml = Parser__SP__MeaningLists__new(TYPE_ML);
ml->type_spec = Specifications__new_generic_from_type_ID(ID_number);
return ml;
}
#line 681 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__type_from_kind(kind *K) {
meaning_list *ml = Parser__SP__MeaningLists__new(TYPE_ML);
ml->type_spec = Specifications__Values__new_generic_CONSTANT(K);
return ml;
}
#line 692 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__determiner(quantifier *quant, int parameter, int w1, int w2) {
meaning_list *ml = Parser__SP__MeaningLists__new_with_words(DETERMINER_ML, w1, w2);
ml->data_attached = STORE_POINTER_quantifier(quant);
ml->score = parameter;
return ml;
}
#line 706 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__time(time_period tp) {
meaning_list *ml = Parser__SP__MeaningLists__new(TIME_ML);
ml->type_spec = Specifications__Conditions__new(Code__Chronology__TimePeriods__store(tp));
return ml;
}
#line 715 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__verb(verb_usage *vu) {
meaning_list *ml = Parser__SP__MeaningLists__new(VERB_ML);
Parser__SP__MeaningLists__attach_data(ml, STORE_POINTER_verb_usage(vu));
return ml;
}
#line 724 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__preposition(preposition_usage *pu) {
meaning_list *ml = Parser__SP__MeaningLists__new(PREP_ML);
Parser__SP__MeaningLists__attach_data(ml, STORE_POINTER_preposition_usage(pu));
return ml;
}
#line 733 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__option(int opt_num) {
meaning_list *ml = Parser__SP__MeaningLists__new(OPTION_ML);
ml->type_spec = Specifications__Conditions__new_TEST_PHRASE_OPTION(opt_num);
return ml;
}
#line 744 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__action(action_pattern *ap) {
meaning_list *ml = Parser__SP__MeaningLists__new(ACTION_ML);
ml->type_spec = Specifications__Conditions__new_TEST_ACTION(ap);
return ml;
}
meaning_list *Parser__SP__MeaningLists__pastaction(action_pattern *ap) {
meaning_list *ml = Parser__SP__MeaningLists__new(ACTION_ML);
ml->type_spec = Specifications__Conditions__new_TEST_PAST_ACTION(ap);
return ml;
}
#line 759 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__say_verb(verb_conjugation *vc, int neg) {
meaning_list *ml = Parser__SP__MeaningLists__new(SAY_VERB_ML);
Parser__SP__MeaningLists__attach_data(ml, STORE_POINTER_verb_conjugation(vc));
Parser__SP__MeaningLists__set_score(ml, neg);
return ml;
}
#line 769 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__say_modal_verb(verb_conjugation *vc) {
meaning_list *ml = Parser__SP__MeaningLists__new(SAY_MODAL_VERB_ML);
Parser__SP__MeaningLists__attach_data(ml, STORE_POINTER_verb_conjugation(vc));
return ml;
}
#line 779 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__say_adjective(adjectival_phrase *aph) {
meaning_list *ml = Parser__SP__MeaningLists__new(SAY_ADJECTIVE_ML);
Parser__SP__MeaningLists__attach_data(ml, STORE_POINTER_adjectival_phrase(aph));
return ml;
}
#line 790 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__copy(meaning_list *ml_to, meaning_list *ml_from) {
ml_to->em = ml_from->em;
ml_to->next_alternative = ml_from->next_alternative;
ml_to->sibling = ml_from->sibling;
ml_to->child = ml_from->child;
ml_to->type_spec = ml_from->type_spec;
ml_to->score = ml_from->score;
ml_to->production = ml_from->production;
ml_to->word_ref1 = ml_from->word_ref1;
ml_to->word_ref2 = ml_from->word_ref2;
ml_to->data_attached = ml_from->data_attached;
}
#line 806 "inform7/Chapter 12/Meaning Lists.w"
unsigned int Parser__SP__MeaningLists__production(meaning_list *ml) {
return ml->production;
}
void Parser__SP__MeaningLists__set_production(meaning_list *ml, unsigned int pr) {
ml->production = pr;
}
#line 816 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__right(meaning_list *ml) {
return ml->sibling;
}
void Parser__SP__MeaningLists__set_right(meaning_list *ml, meaning_list *ml2) {
ml->sibling = ml2;
}
meaning_list *Parser__SP__MeaningLists__down(meaning_list *ml) {
return ml->child;
}
void Parser__SP__MeaningLists__set_down(meaning_list *ml, meaning_list *ml2) {
ml->child = ml2;
}
#line 832 "inform7/Chapter 12/Meaning Lists.w"
meaning_list *Parser__SP__MeaningLists__sideways(meaning_list *ml) {
return ml->next_alternative;
}
int Parser__SP__MeaningLists__match_score(meaning_list *ml) {
return ml->score;
}
void Parser__SP__MeaningLists__set_score(meaning_list *ml, int s) {
ml->score = s;
}
#line 849 "inform7/Chapter 12/Meaning Lists.w"
void Parser__SP__MeaningLists__set_text(meaning_list *ml, int w1, int w2) {
if (w1<0) { ml->word_ref1 = -1; ml->word_ref2 = -1; }
else { ml->word_ref1 = w1; ml->word_ref2 = w2; }
}
void Parser__SP__MeaningLists__get_text(meaning_list *ml, int *w1, int *w2) {
*w1 = ml->word_ref1; *w2 = ml->word_ref2;
}
#line 861 "inform7/Chapter 12/Meaning Lists.w"
excerpt_meaning *Parser__SP__MeaningLists__meaning(meaning_list *ml) {
return ml->em;
}
void Parser__SP__MeaningLists__set_meaning(meaning_list *ml, excerpt_meaning *em) {
ml->em = em;
}
#line 871 "inform7/Chapter 12/Meaning Lists.w"
specification *Parser__SP__MeaningLists__get_attached_spec(meaning_list *ml) {
return ml->type_spec;
}
void Parser__SP__MeaningLists__attach_spec(meaning_list *ml, specification *spec) {
ml->type_spec = spec;
}
#line 882 "inform7/Chapter 12/Meaning Lists.w"
general_pointer Parser__SP__MeaningLists__get_attached_data(meaning_list *ml) {
return ml->data_attached;
}
void Parser__SP__MeaningLists__attach_data(meaning_list *ml, general_pointer data) {
ml->data_attached = data;
}
#line 83 "inform7/Chapter 12/Parse Excerpts.w"
int force_maximal_parsing = FALSE;
meaning_list *Parser__SP__parse_excerpt_maximal(unsigned int mc_bitmap, int w1, int w2) {
int s = force_maximal_parsing;
force_maximal_parsing = TRUE;
meaning_list *ml = Parser__SP__parse_excerpt(mc_bitmap, w1, w2);
force_maximal_parsing = s;
return ml;
}
meaning_list *Parser__SP__parse_excerpt(unsigned int mc_bitmap, int w1, int w2) {
int parsing_mode, h;
meaning_list *results = NULL;
no_calls_to_parse_excerpt++;
if ((w1<0) || (w2<w1)) return NULL;
while (Text__paired_brackets(w1, w2)) { w1++; w2--; }
if (w2<w1) return NULL;
h = 0;
{
#line 135 "inform7/Chapter 12/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 104 "inform7/Chapter 12/Parse Excerpts.w"
;
{
#line 150 "inform7/Chapter 12/Parse Excerpts.w"
if (mc_bitmap & SAY_PHRASE_MC) {
char *tx = Text__word_raw_text(w1);
if ((tx[0]) && (isupper(tx[0])) && (Text__Vocabulary__used_case_sensitively(Text__word(w1))))
h = h | CAPITALISED_VARIANT_FORM;
}
}
#line 105 "inform7/Chapter 12/Parse Excerpts.w"
;
{
#line 161 "inform7/Chapter 12/Parse Excerpts.w"
if (parsing_mode & PARAMETRISED_PM) {
if ((mc_bitmap & SAY_PHRASE_MC) == 0) {
Text__Languages__remove_the(&w1, &w2);
}
} else {
if ((w1<w2) && (Text__Languages__test_word(w1, article_NTM))) w1++;
}
}
#line 106 "inform7/Chapter 12/Parse Excerpts.w"
;
h = h | Semantics__Nouns__ExcerptMeanings__hash_code(w1, w2);
LOGIF(EXCERPT_PARSING,
"Parsing excerpt <$W> hash %08x mc $p mode %d\n", w1, w2, h, mc_bitmap, parsing_mode);
switch(parsing_mode) {
case EXACT_PM:
{
#line 187 "inform7/Chapter 12/Parse Excerpts.w"
meaning_list *ml;
vocabulary_entry *v = Text__word(w1);
if (v == NULL) internal_error("Unidentified word when parsing");
if ((v->flags) & mc_bitmap)
for (ml = v->start_list; ml; ml = ml->next_alternative)
{
#line 197 "inform7/Chapter 12/Parse Excerpts.w"
if (EXCERPT_MEANING_RELEVANT(ml) && (h == ml->em->excerpt_hash)) {
EXAMINE_EXCERPT_MEANING_IN_DETAIL;
if (ml->em->no_em_tokens == (w2-w1+1)) {
int j, k, err;
for (j=0, k=w1, err = FALSE; j<ml->em->no_em_tokens; j++, k++)
if (ml->em->em_tokens[j] != Text__word(k)) { err=TRUE; break; }
if (err == FALSE) {
meaning_list *further_result = Parser__SP__MeaningLists__new(ml->em->meaning_code);
further_result->em = ml->em;
further_result->next_alternative = results;
further_result->score = 1;
results = further_result;
}
}
}
}
#line 192 "inform7/Chapter 12/Parse Excerpts.w"
;
}
#line 114 "inform7/Chapter 12/Parse Excerpts.w"
; break;
case MAXIMAL_PM:
{
#line 216 "inform7/Chapter 12/Parse Excerpts.w"
vocabulary_entry *v = Text__word(w1);
if (v == NULL) internal_error("Unidentified word when parsing");
if ((v->flags) & mc_bitmap) {
meaning_list *ml, *best_ml = NULL; int best_score = 0;
for (ml = v->start_list; ml; ml = ml->next_alternative)
{
#line 234 "inform7/Chapter 12/Parse Excerpts.w"
if (EXCERPT_MEANING_RELEVANT(ml) &&
((h & ml->em->excerpt_hash) == ml->em->excerpt_hash)) {
EXAMINE_EXCERPT_MEANING_IN_DETAIL;
if (ml->em->no_em_tokens <= w2-w1+1) {
int j, k, err;
for (err=FALSE, j=0, k=w1; j<ml->em->no_em_tokens; j++, k++)
if (ml->em->em_tokens[j] != Text__word(k)) { err = TRUE; break; }
if ((err == FALSE) && (j>best_score)) {
best_ml = ml; best_score = j;
}
}
}
}
#line 221 "inform7/Chapter 12/Parse Excerpts.w"
;
if (best_ml) {
results = Parser__SP__MeaningLists__new(best_ml->em->meaning_code);
results->em = best_ml->em;
results->score = best_score;
}
}
}
#line 115 "inform7/Chapter 12/Parse Excerpts.w"
; break;
case PARAMETRISED_PM:
{
#line 252 "inform7/Chapter 12/Parse Excerpts.w"
int i;
vocabulary_entry *v = Text__word(w1);
if (v == NULL) internal_error("Unidentified word when parsing");
meaning_list *ml;
if (mc_bitmap & SAY_PHRASE_MC) {
for (ml = blank_says_ml; ml; ml = ml->next_alternative) {
int mw1, mw2;
meaning_list *this_result =
Parser__SP__MeaningLists__new_with_words(SAY_PHRASE_MC, w1, w2);
Parser__SP__MeaningLists__get_text(this_result, &mw1, &mw2);
Parser__SP__MeaningLists__copy(this_result, ml);
Parser__SP__MeaningLists__set_text(this_result, mw1, mw2);
this_result->child = ML_PLAIN(w1, w2);
this_result->next_alternative = results;
results = this_result;
no_meanings_tried++, no_meanings_tried_in_detail++;
}
}
for (ml = v->start_list; ml; ml = ml->next_alternative)
{
#line 289 "inform7/Chapter 12/Parse Excerpts.w"
if (EXCERPT_MEANING_RELEVANT(ml) &&
((h & ml->em->excerpt_hash) == ml->em->excerpt_hash)) {
int no_tokens_to_match = ml->em->no_em_tokens;
int saved_w1 = w1, saved_w2 = w2;
int params_w1[MAX_TOKENS_PER_EXCERPT_MEANING], params_w2[MAX_TOKENS_PER_EXCERPT_MEANING];
int ph_opt_w1 = -1, ph_opt_w2 = -1;
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 318 "inform7/Chapter 12/Parse Excerpts.w"
phrase *ph = RETRIEVE_POINTER_phrase(ml->em->data);
if (Code__Routines__ToPhrases__allows_options(ph)) {
LOGIF(EXCERPT_PARSING, "Looking for phrase options\n");
for (bl=0, scan_pos=w1+1; scan_pos<w2; scan_pos++) {
if ((Text__word(scan_pos) == COMMA_V) && (bl==0)) {
ph_opt_w1 = scan_pos+1; ph_opt_w2 = w2; w2 = scan_pos-1;
LOGIF(EXCERPT_PARSING, "Found phrase options <$W>\n",
ph_opt_w1, ph_opt_w2);
break;
}
{
#line 396 "inform7/Chapter 12/Parse Excerpts.w"
if ((Text__word(scan_pos) == OPENBRACKET_V) || (Text__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Text__word(scan_pos) == CLOSEBRACKET_V) || (Text__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 328 "inform7/Chapter 12/Parse Excerpts.w"
;
}
}
}
#line 299 "inform7/Chapter 12/Parse Excerpts.w"
;
for (err=FALSE, j=0, scan_pos=w1, t=0, bl=0; (j<no_tokens_to_match) && (scan_pos<=w2); j++) {
LOGIF(EXCERPT_PARSING, "j=%d, scan_pos=%d, t=%d\n", j, scan_pos, t);
vocabulary_entry *this_word = ml->em->em_tokens[j];
if (this_word)
{
#line 335 "inform7/Chapter 12/Parse Excerpts.w"
if (this_word != Text__word(scan_pos)) { err=TRUE; break; }
if (this_word == word_to_suppress_in_phrases) { err=TRUE; break; }
scan_pos++;
}
#line 303 "inform7/Chapter 12/Parse Excerpts.w"
else if (j == no_tokens_to_match-1)
{
#line 342 "inform7/Chapter 12/Parse Excerpts.w"
params_w1[t] = scan_pos; params_w2[t] = w2; t++;
scan_pos = w2+1;
}
#line 305 "inform7/Chapter 12/Parse Excerpts.w"
else
{
#line 348 "inform7/Chapter 12/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 (ml->em->em_tokens[j+1+fixed_words_at_end] == NULL) {
fixed_words_at_end = 0; break;
}
if (fixed_words_at_end > 0) {
params_w1[t] = scan_pos; params_w2[t] = w2 - fixed_words_at_end; t++;
scan_pos = w2 - fixed_words_at_end + 1;
} else {
vocabulary_entry *sentinel = ml->em->em_tokens[j+1];
int bl_initial = bl;
int start_word = scan_pos;
err = TRUE;
while (scan_pos <= w2) {
{
#line 396 "inform7/Chapter 12/Parse Excerpts.w"
if ((Text__word(scan_pos) == OPENBRACKET_V) || (Text__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Text__word(scan_pos) == CLOSEBRACKET_V) || (Text__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 364 "inform7/Chapter 12/Parse Excerpts.w"
;
if ((bl == bl_initial) && (scan_pos > start_word) &&
(sentinel == Text__word(scan_pos))) { err = FALSE; break; }
if (bl < bl_initial) break;
scan_pos++;
}
params_w1[t] = start_word; params_w2[t] = scan_pos-1; t++;
}
}
#line 307 "inform7/Chapter 12/Parse Excerpts.w"
;
}
LOGIF(EXCERPT_PARSING, "outcome has err=%d\n", err);
{
#line 376 "inform7/Chapter 12/Parse Excerpts.w"
int x;
if (j<no_tokens_to_match) err = TRUE;
if (scan_pos<=w2) err = TRUE;
if (err == FALSE)
for (x=0; x<t; x++) {
if ((params_w1[x]<0) || (params_w1[x]>params_w2[x])) err = TRUE;
else {
int bl = 0;
int scan_pos;
for (scan_pos=params_w1[x]; scan_pos<=params_w2[x]; scan_pos++) {
{
#line 396 "inform7/Chapter 12/Parse Excerpts.w"
if ((Text__word(scan_pos) == OPENBRACKET_V) || (Text__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Text__word(scan_pos) == CLOSEBRACKET_V) || (Text__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 386 "inform7/Chapter 12/Parse Excerpts.w"
;
if (bl < 0) err = TRUE;
}
if (bl != 0) err = TRUE;
}
}
}
#line 310 "inform7/Chapter 12/Parse Excerpts.w"
;
if (err == FALSE)
{
#line 403 "inform7/Chapter 12/Parse Excerpts.w"
meaning_list *last_param = NULL;
meaning_list *this_result =
Parser__SP__MeaningLists__new_with_words(ml->em->meaning_code, w1, w2);
this_result->em = ml->em;
this_result->next_alternative = results;
this_result->score = 1;
if (ph_opt_w1 >= 0) {
this_result->child = ML_PLAIN(ph_opt_w1, ph_opt_w2);
this_result->child->production = PHR_OPT_ML;
last_param = this_result->child;
}
int x;
for (x=0; x<t; x++) {
meaning_list *ml2;
ml2 = ML_PLAIN(params_w1[x], params_w2[x]);
if (last_param) last_param->sibling = ml2;
else this_result->child = ml2;
last_param = ml2;
}
results = this_result;
}
#line 311 "inform7/Chapter 12/Parse Excerpts.w"
;
w1 = saved_w1; w2 = saved_w2;
}
}
#line 271 "inform7/Chapter 12/Parse Excerpts.w"
;
if (w2>w1) {
v = Text__word(w2);
if (v == NULL) internal_error("Unidentified word when parsing");
for (ml = v->end_list; ml; ml = ml->next_alternative)
{
#line 289 "inform7/Chapter 12/Parse Excerpts.w"
if (EXCERPT_MEANING_RELEVANT(ml) &&
((h & ml->em->excerpt_hash) == ml->em->excerpt_hash)) {
int no_tokens_to_match = ml->em->no_em_tokens;
int saved_w1 = w1, saved_w2 = w2;
int params_w1[MAX_TOKENS_PER_EXCERPT_MEANING], params_w2[MAX_TOKENS_PER_EXCERPT_MEANING];
int ph_opt_w1 = -1, ph_opt_w2 = -1;
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 318 "inform7/Chapter 12/Parse Excerpts.w"
phrase *ph = RETRIEVE_POINTER_phrase(ml->em->data);
if (Code__Routines__ToPhrases__allows_options(ph)) {
LOGIF(EXCERPT_PARSING, "Looking for phrase options\n");
for (bl=0, scan_pos=w1+1; scan_pos<w2; scan_pos++) {
if ((Text__word(scan_pos) == COMMA_V) && (bl==0)) {
ph_opt_w1 = scan_pos+1; ph_opt_w2 = w2; w2 = scan_pos-1;
LOGIF(EXCERPT_PARSING, "Found phrase options <$W>\n",
ph_opt_w1, ph_opt_w2);
break;
}
{
#line 396 "inform7/Chapter 12/Parse Excerpts.w"
if ((Text__word(scan_pos) == OPENBRACKET_V) || (Text__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Text__word(scan_pos) == CLOSEBRACKET_V) || (Text__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 328 "inform7/Chapter 12/Parse Excerpts.w"
;
}
}
}
#line 299 "inform7/Chapter 12/Parse Excerpts.w"
;
for (err=FALSE, j=0, scan_pos=w1, t=0, bl=0; (j<no_tokens_to_match) && (scan_pos<=w2); j++) {
LOGIF(EXCERPT_PARSING, "j=%d, scan_pos=%d, t=%d\n", j, scan_pos, t);
vocabulary_entry *this_word = ml->em->em_tokens[j];
if (this_word)
{
#line 335 "inform7/Chapter 12/Parse Excerpts.w"
if (this_word != Text__word(scan_pos)) { err=TRUE; break; }
if (this_word == word_to_suppress_in_phrases) { err=TRUE; break; }
scan_pos++;
}
#line 303 "inform7/Chapter 12/Parse Excerpts.w"
else if (j == no_tokens_to_match-1)
{
#line 342 "inform7/Chapter 12/Parse Excerpts.w"
params_w1[t] = scan_pos; params_w2[t] = w2; t++;
scan_pos = w2+1;
}
#line 305 "inform7/Chapter 12/Parse Excerpts.w"
else
{
#line 348 "inform7/Chapter 12/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 (ml->em->em_tokens[j+1+fixed_words_at_end] == NULL) {
fixed_words_at_end = 0; break;
}
if (fixed_words_at_end > 0) {
params_w1[t] = scan_pos; params_w2[t] = w2 - fixed_words_at_end; t++;
scan_pos = w2 - fixed_words_at_end + 1;
} else {
vocabulary_entry *sentinel = ml->em->em_tokens[j+1];
int bl_initial = bl;
int start_word = scan_pos;
err = TRUE;
while (scan_pos <= w2) {
{
#line 396 "inform7/Chapter 12/Parse Excerpts.w"
if ((Text__word(scan_pos) == OPENBRACKET_V) || (Text__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Text__word(scan_pos) == CLOSEBRACKET_V) || (Text__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 364 "inform7/Chapter 12/Parse Excerpts.w"
;
if ((bl == bl_initial) && (scan_pos > start_word) &&
(sentinel == Text__word(scan_pos))) { err = FALSE; break; }
if (bl < bl_initial) break;
scan_pos++;
}
params_w1[t] = start_word; params_w2[t] = scan_pos-1; t++;
}
}
#line 307 "inform7/Chapter 12/Parse Excerpts.w"
;
}
LOGIF(EXCERPT_PARSING, "outcome has err=%d\n", err);
{
#line 376 "inform7/Chapter 12/Parse Excerpts.w"
int x;
if (j<no_tokens_to_match) err = TRUE;
if (scan_pos<=w2) err = TRUE;
if (err == FALSE)
for (x=0; x<t; x++) {
if ((params_w1[x]<0) || (params_w1[x]>params_w2[x])) err = TRUE;
else {
int bl = 0;
int scan_pos;
for (scan_pos=params_w1[x]; scan_pos<=params_w2[x]; scan_pos++) {
{
#line 396 "inform7/Chapter 12/Parse Excerpts.w"
if ((Text__word(scan_pos) == OPENBRACKET_V) || (Text__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Text__word(scan_pos) == CLOSEBRACKET_V) || (Text__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 386 "inform7/Chapter 12/Parse Excerpts.w"
;
if (bl < 0) err = TRUE;
}
if (bl != 0) err = TRUE;
}
}
}
#line 310 "inform7/Chapter 12/Parse Excerpts.w"
;
if (err == FALSE)
{
#line 403 "inform7/Chapter 12/Parse Excerpts.w"
meaning_list *last_param = NULL;
meaning_list *this_result =
Parser__SP__MeaningLists__new_with_words(ml->em->meaning_code, w1, w2);
this_result->em = ml->em;
this_result->next_alternative = results;
this_result->score = 1;
if (ph_opt_w1 >= 0) {
this_result->child = ML_PLAIN(ph_opt_w1, ph_opt_w2);
this_result->child->production = PHR_OPT_ML;
last_param = this_result->child;
}
int x;
for (x=0; x<t; x++) {
meaning_list *ml2;
ml2 = ML_PLAIN(params_w1[x], params_w2[x]);
if (last_param) last_param->sibling = ml2;
else this_result->child = ml2;
last_param = ml2;
}
results = this_result;
}
#line 311 "inform7/Chapter 12/Parse Excerpts.w"
;
w1 = saved_w1; w2 = saved_w2;
}
}
#line 276 "inform7/Chapter 12/Parse Excerpts.w"
;
}
for (i=w1+1; i<w2; i++) {
v = Text__word(i);
if (v == NULL) internal_error("Unidentified word when parsing");
for (ml = v->middle_list; ml; ml = ml->next_alternative)
{
#line 289 "inform7/Chapter 12/Parse Excerpts.w"
if (EXCERPT_MEANING_RELEVANT(ml) &&
((h & ml->em->excerpt_hash) == ml->em->excerpt_hash)) {
int no_tokens_to_match = ml->em->no_em_tokens;
int saved_w1 = w1, saved_w2 = w2;
int params_w1[MAX_TOKENS_PER_EXCERPT_MEANING], params_w2[MAX_TOKENS_PER_EXCERPT_MEANING];
int ph_opt_w1 = -1, ph_opt_w2 = -1;
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 318 "inform7/Chapter 12/Parse Excerpts.w"
phrase *ph = RETRIEVE_POINTER_phrase(ml->em->data);
if (Code__Routines__ToPhrases__allows_options(ph)) {
LOGIF(EXCERPT_PARSING, "Looking for phrase options\n");
for (bl=0, scan_pos=w1+1; scan_pos<w2; scan_pos++) {
if ((Text__word(scan_pos) == COMMA_V) && (bl==0)) {
ph_opt_w1 = scan_pos+1; ph_opt_w2 = w2; w2 = scan_pos-1;
LOGIF(EXCERPT_PARSING, "Found phrase options <$W>\n",
ph_opt_w1, ph_opt_w2);
break;
}
{
#line 396 "inform7/Chapter 12/Parse Excerpts.w"
if ((Text__word(scan_pos) == OPENBRACKET_V) || (Text__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Text__word(scan_pos) == CLOSEBRACKET_V) || (Text__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 328 "inform7/Chapter 12/Parse Excerpts.w"
;
}
}
}
#line 299 "inform7/Chapter 12/Parse Excerpts.w"
;
for (err=FALSE, j=0, scan_pos=w1, t=0, bl=0; (j<no_tokens_to_match) && (scan_pos<=w2); j++) {
LOGIF(EXCERPT_PARSING, "j=%d, scan_pos=%d, t=%d\n", j, scan_pos, t);
vocabulary_entry *this_word = ml->em->em_tokens[j];
if (this_word)
{
#line 335 "inform7/Chapter 12/Parse Excerpts.w"
if (this_word != Text__word(scan_pos)) { err=TRUE; break; }
if (this_word == word_to_suppress_in_phrases) { err=TRUE; break; }
scan_pos++;
}
#line 303 "inform7/Chapter 12/Parse Excerpts.w"
else if (j == no_tokens_to_match-1)
{
#line 342 "inform7/Chapter 12/Parse Excerpts.w"
params_w1[t] = scan_pos; params_w2[t] = w2; t++;
scan_pos = w2+1;
}
#line 305 "inform7/Chapter 12/Parse Excerpts.w"
else
{
#line 348 "inform7/Chapter 12/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 (ml->em->em_tokens[j+1+fixed_words_at_end] == NULL) {
fixed_words_at_end = 0; break;
}
if (fixed_words_at_end > 0) {
params_w1[t] = scan_pos; params_w2[t] = w2 - fixed_words_at_end; t++;
scan_pos = w2 - fixed_words_at_end + 1;
} else {
vocabulary_entry *sentinel = ml->em->em_tokens[j+1];
int bl_initial = bl;
int start_word = scan_pos;
err = TRUE;
while (scan_pos <= w2) {
{
#line 396 "inform7/Chapter 12/Parse Excerpts.w"
if ((Text__word(scan_pos) == OPENBRACKET_V) || (Text__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Text__word(scan_pos) == CLOSEBRACKET_V) || (Text__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 364 "inform7/Chapter 12/Parse Excerpts.w"
;
if ((bl == bl_initial) && (scan_pos > start_word) &&
(sentinel == Text__word(scan_pos))) { err = FALSE; break; }
if (bl < bl_initial) break;
scan_pos++;
}
params_w1[t] = start_word; params_w2[t] = scan_pos-1; t++;
}
}
#line 307 "inform7/Chapter 12/Parse Excerpts.w"
;
}
LOGIF(EXCERPT_PARSING, "outcome has err=%d\n", err);
{
#line 376 "inform7/Chapter 12/Parse Excerpts.w"
int x;
if (j<no_tokens_to_match) err = TRUE;
if (scan_pos<=w2) err = TRUE;
if (err == FALSE)
for (x=0; x<t; x++) {
if ((params_w1[x]<0) || (params_w1[x]>params_w2[x])) err = TRUE;
else {
int bl = 0;
int scan_pos;
for (scan_pos=params_w1[x]; scan_pos<=params_w2[x]; scan_pos++) {
{
#line 396 "inform7/Chapter 12/Parse Excerpts.w"
if ((Text__word(scan_pos) == OPENBRACKET_V) || (Text__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Text__word(scan_pos) == CLOSEBRACKET_V) || (Text__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 386 "inform7/Chapter 12/Parse Excerpts.w"
;
if (bl < 0) err = TRUE;
}
if (bl != 0) err = TRUE;
}
}
}
#line 310 "inform7/Chapter 12/Parse Excerpts.w"
;
if (err == FALSE)
{
#line 403 "inform7/Chapter 12/Parse Excerpts.w"
meaning_list *last_param = NULL;
meaning_list *this_result =
Parser__SP__MeaningLists__new_with_words(ml->em->meaning_code, w1, w2);
this_result->em = ml->em;
this_result->next_alternative = results;
this_result->score = 1;
if (ph_opt_w1 >= 0) {
this_result->child = ML_PLAIN(ph_opt_w1, ph_opt_w2);
this_result->child->production = PHR_OPT_ML;
last_param = this_result->child;
}
int x;
for (x=0; x<t; x++) {
meaning_list *ml2;
ml2 = ML_PLAIN(params_w1[x], params_w2[x]);
if (last_param) last_param->sibling = ml2;
else this_result->child = ml2;
last_param = ml2;
}
results = this_result;
}
#line 311 "inform7/Chapter 12/Parse Excerpts.w"
;
w1 = saved_w1; w2 = saved_w2;
}
}
#line 282 "inform7/Chapter 12/Parse Excerpts.w"
;
}
}
#line 116 "inform7/Chapter 12/Parse Excerpts.w"
; break;
case SUBSET_PM:
{
#line 435 "inform7/Chapter 12/Parse Excerpts.w"
int i, j, k;
if ((w1 == w2) && ((Text__Vocabulary__test_flags(w1, NUMBER_MC)) != 0)) goto SubsetFailed;
for (i=w1, j=-1, k=-1; i<=w2; i++) {
vocabulary_entry *v = Text__word(i);
if (v == NULL) internal_error("Unidentified word when parsing");
if (Text__Languages__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 = Text__word(k);
meaning_list *ml;
for (ml = v->subset_list; ml; ml = ml->next_alternative)
{
#line 455 "inform7/Chapter 12/Parse Excerpts.w"
if (EXCERPT_MEANING_RELEVANT(ml) && ((h & ml->em->excerpt_hash) == h)) {
EXAMINE_EXCERPT_MEANING_IN_DETAIL;
if (w2-w1 < ml->em->no_em_tokens) {
int err = FALSE;
if (ml->em->meaning_code == NAMETAG_MC) {
nametag *nt = RETRIEVE_POINTER_nametag(ml->em->data);
if ((nt) && (Data__Nametags__exactitude(nt))) {
LOGIF(EXCERPT_PARSING, "Require exact matching of $M\n", ml->em);
err = TRUE;
if (ml->em->no_em_tokens == (w2-w1+1)) {
for (j=0, k=w1, err = FALSE; j<ml->em->no_em_tokens; j++, k++)
if (ml->em->em_tokens[j] != Text__word(k)) {
err=TRUE; break;
}
}
goto SubsetMatchDecided;
}
}
for (k=w1; k<=w2; k++) {
err = TRUE;
for (j=0; j<ml->em->no_em_tokens; j++)
if (ml->em->em_tokens[j] == Text__word(k)) err=FALSE;
if (err) break;
}
SubsetMatchDecided:
if (err == FALSE) {
meaning_list *this_result =
Parser__SP__MeaningLists__new(ml->em->meaning_code);
this_result->em = ml->em;
this_result->next_alternative = results;
this_result->score = 100-((ml->em->no_em_tokens) - (w2-w1));
results = this_result;
}
}
}
}
#line 448 "inform7/Chapter 12/Parse Excerpts.w"
;
}
SubsetFailed: ;
}
#line 117 "inform7/Chapter 12/Parse Excerpts.w"
; break;
case 0: LOG("mc_bitmap: $p\n", mc_bitmap); internal_error("Unknown parsing mode");
default: LOG("mc_bitmap: $p\n", mc_bitmap); internal_error("Mixed parsing modes");
}
LOGIF(EXCERPT_PARSING, "Completed:\n$m", results);
meaning_list *loopy; for (loopy = results; loopy; loopy = loopy->next_alternative)
no_matched_ems++;
if (results) no_successful_calls_to_parse_excerpt++;
return results;
}
#line 521 "inform7/Chapter 12/Parse Excerpts.w"
void Parser__SP__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__Aspects__on(EXCERPT_MEANINGS_DA)) Semantics__Nouns__ExcerptMeanings__log_all();
}
#line 21 "inform7/Chapter 12/Parse Literals.w"
int s_literal_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 27 "inform7/Chapter 12/Parse Literals.w"
*X = R[1];
kind *K = RP[1];
meaning_list *ml = Parser__SP__MeaningLists__new(LITERAL_ML);
specification *spec = Specifications__Values__new_actual_CONSTANT(K);
spec->word_ref1 = w1; spec->word_ref2 = w2;
Parser__SP__MeaningLists__attach_spec(ml, spec);
*XP = ml;
}
#line 22 "inform7/Chapter 12/Parse Literals.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 23 "inform7/Chapter 12/Parse Literals.w"
#line 48 "inform7/Chapter 12/Parse Literals.w"
int literal_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = R[1]; *XP = K_number;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = -R[1]; *XP = K_number;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1]; *XP = K_text;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = R[1]; *XP = K_text;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = R[1]; *XP = K_real_number;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = R[1]; *XP = K_truth_state;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = R[1]; *XP = K_unicode_character;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = R[1]; *XP = K_time /* times\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *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 59 "inform7/Chapter 12/Parse Literals.w"
int literal_unit_notation_NTMR(int w1, int w2, int *X, void **XP) {
#line 61 "inform7/Chapter 12/Parse Literals.w"
literal_pattern *lp;
LOOP_OVER(lp, literal_pattern) {
int val;
kind *K = Semantics__Nouns__LiteralPatterns__match(lp, w1, w2, &val);
if (K) { *X = val; *XP = K; return TRUE; }
}
return FALSE;
}
#line 77 "inform7/Chapter 12/Parse Literals.w"
int cardinal_number_in_words_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 91 "inform7/Chapter 12/Parse Literals.w"
#line 95 "inform7/Chapter 12/Parse Literals.w"
int ordinal_number_in_words_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 109 "inform7/Chapter 12/Parse Literals.w"
#line 122 "inform7/Chapter 12/Parse Literals.w"
int cardinal_number_NTMR(int w1, int w2, int *X, void **XP) {
#line 123 "inform7/Chapter 12/Parse Literals.w"
if (Text__Vocabulary__test_flags(w1, NUMBER_MC)) {
*X = Text__Vocabulary__get_literal_number_value(Text__word(w1));
{
#line 158 "inform7/Chapter 12/Parse Literals.w"
if ((((*X) > 32767) || ((*X) < -32768)) &&
(Code__VirtualMachines__is_16_bit())) {
Problems__sentence_problem(_P_(C12LiteralOverflow),
"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: */
Text__Vocabulary__set_literal_number_value(Text__word(w1), 1);
return FALSE;
}
}
#line 125 "inform7/Chapter 12/Parse Literals.w"
;
return TRUE;
}
return FALSE;
}
int ordinal_number_NTMR(int w1, int w2, int *X, void **XP) {
#line 132 "inform7/Chapter 12/Parse Literals.w"
if (Text__Vocabulary__test_flags(w1, ORDINAL_MC)) {
*X = Text__Vocabulary__get_literal_number_value(Text__word(w1));
{
#line 158 "inform7/Chapter 12/Parse Literals.w"
if ((((*X) > 32767) || ((*X) < -32768)) &&
(Code__VirtualMachines__is_16_bit())) {
Problems__sentence_problem(_P_(C12LiteralOverflow),
"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: */
Text__Vocabulary__set_literal_number_value(Text__word(w1), 1);
return FALSE;
}
}
#line 134 "inform7/Chapter 12/Parse Literals.w"
;
return TRUE;
}
return FALSE;
}
#line 143 "inform7/Chapter 12/Parse Literals.w"
int cardinal_number_unlimited_NTMR(int w1, int w2, int *X, void **XP) {
#line 144 "inform7/Chapter 12/Parse Literals.w"
if (Text__Vocabulary__test_flags(w1, NUMBER_MC)) {
*X = Text__Vocabulary__get_literal_number_value(Text__word(w1));
return TRUE;
}
return FALSE;
}
#line 176 "inform7/Chapter 12/Parse Literals.w"
int quoted_text_NTMR(int w1, int w2, int *X, void **XP) {
#line 177 "inform7/Chapter 12/Parse Literals.w"
if ((w1 >= 0) && (Text__Vocabulary__test_flags(w1, TEXT_MC+TEXTWITHSUBS_MC))) {
*X = w1; return TRUE;
}
return FALSE;
}
int quoted_text_with_subs_NTMR(int w1, int w2, int *X, void **XP) {
#line 184 "inform7/Chapter 12/Parse Literals.w"
if ((w1 >= 0) && (Text__Vocabulary__test_flags(w1, TEXTWITHSUBS_MC))) {
*X = w1; return TRUE;
}
return FALSE;
}
int quoted_text_without_subs_NTMR(int w1, int w2, int *X, void **XP) {
#line 191 "inform7/Chapter 12/Parse Literals.w"
if ((w1 >= 0) && (Text__Vocabulary__test_flags(w1, TEXT_MC))) {
*X = w1; return TRUE;
}
return FALSE;
}
#line 201 "inform7/Chapter 12/Parse Literals.w"
int empty_text_NTMR(int w1, int w2, int *X, void **XP) {
#line 202 "inform7/Chapter 12/Parse Literals.w"
if ((w1 >= 0) && (Text__compare_word_by_strcmp(w1, "\"\""))) {
*X = w1; return TRUE;
}
return FALSE;
}
#line 212 "inform7/Chapter 12/Parse Literals.w"
int response_letter_NTMR(int w1, int w2, int *X, void **XP) {
#line 213 "inform7/Chapter 12/Parse Literals.w"
char *p = Text__word_raw_text(w1);
if ((p) && (p[0] >= 'A') && (p[0] <= 'Z') && (p[1] == 0)) {
*X = p[0] - 'A';
return TRUE;
}
return FALSE;
}
#line 228 "inform7/Chapter 12/Parse Literals.w"
int literal_truth_state_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 231 "inform7/Chapter 12/Parse Literals.w"
#line 235 "inform7/Chapter 12/Parse Literals.w"
int e_notation_problem_issued = FALSE;
#line 242 "inform7/Chapter 12/Parse Literals.w"
int literal_real_number_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0x40490FDB;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0x402DF854;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0x7F800000;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = (int) 0xFF800000;
#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 248 "inform7/Chapter 12/Parse Literals.w"
int literal_real_in_digits_NTMR(int w1, int w2, int *X, void **XP) {
#line 250 "inform7/Chapter 12/Parse Literals.w"
if ((w2-w1 != 0) && (w2-w1 != 2)) return FALSE;
char *p = Text__word_raw_text(w1);
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 276 "inform7/Chapter 12/Parse Literals.w"
if (p[i] == '-') { signbit = 1; i++; }
else if (p[i] == '+') { signbit = 0; i++; }
}
#line 259 "inform7/Chapter 12/Parse Literals.w"
;
{
#line 282 "inform7/Chapter 12/Parse Literals.w"
while (isdigit(p[i])) {
intv = 10.0*intv + (p[i] - '0');
intcount++;
i++;
}
}
#line 260 "inform7/Chapter 12/Parse Literals.w"
;
{
#line 291 "inform7/Chapter 12/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 261 "inform7/Chapter 12/Parse Literals.w"
;
if (intcount + fraccount > 0) {
if ((w2 > w1) || (p[i]))
{
#line 306 "inform7/Chapter 12/Parse Literals.w"
char *q = p + i;
int e_notation_used = FALSE;
if (w2 > w1) {
if (q[0] != 0) return FALSE;
q = Text__word_raw_text(w1 + 1);
if (!((ismultiplicationsign(q[0])) && (q[1] == 0))) return FALSE;
q = Text__word_raw_text(w1 + 2);
} else {
if ((fraccount > 0) && ((q[0] == 'e') || (q[0] == 'E'))) e_notation_used = TRUE;
else if (!(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_words(2, w1, w2);
Problems__handmade_problem(_P_(C12WantonEngineering));
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 263 "inform7/Chapter 12/Parse Literals.w"
;
if ((distinctive) || (TEST_COMPILATION_MODE(CONSTANT_CMODE))) {
*X = construct_float(signbit, intv, fracv, expo);
return TRUE;
}
}
}
return FALSE;
}
#line 353 "inform7/Chapter 12/Parse Literals.w"
int ismultiplicationsign(char c) {
if ((c == 'x') || (c == '*')) return TRUE;
return FALSE;
}
#line 371 "inform7/Chapter 12/Parse Literals.w"
int construct_float(int signbit, double intv, double fracv, int expo) {
/* LOG("construct_float(%d, %g, %g, %d)\n", signbit, intv, fracv, expo); */
double absval = (intv + fracv) * ten_to_the(expo);
int sign = (signbit ? ((int) 0x80000000) : 0x0);
latest_constructed_real = absval; if (signbit) latest_constructed_real = -absval;
if (isinf(absval))
{
#line 435 "inform7/Chapter 12/Parse Literals.w"
return sign | 0x7f800000;
}
#line 378 "inform7/Chapter 12/Parse Literals.w"
;
if (isnan(absval))
{
#line 440 "inform7/Chapter 12/Parse Literals.w"
return sign | 0x7fc00000;
}
#line 379 "inform7/Chapter 12/Parse Literals.w"
;
double mant = frexp(absval, &expo);
{
#line 397 "inform7/Chapter 12/Parse Literals.w"
if ((0.5 <= mant) && (mant < 1.0)) {
mant *= 2.0;
expo--;
} else if (mant == 0.0) {
expo = 0;
} else
{
#line 435 "inform7/Chapter 12/Parse Literals.w"
return sign | 0x7f800000;
}
#line 402 "inform7/Chapter 12/Parse Literals.w"
;
}
#line 382 "inform7/Chapter 12/Parse Literals.w"
;
if (expo >= 128)
{
#line 435 "inform7/Chapter 12/Parse Literals.w"
return sign | 0x7f800000;
}
#line 384 "inform7/Chapter 12/Parse Literals.w"
;
if (expo < -126)
{
#line 408 "inform7/Chapter 12/Parse Literals.w"
mant = ldexp(mant, 126 + expo);
expo = 0; /* 0 now represents 10 to the minus 127 */
}
#line 385 "inform7/Chapter 12/Parse Literals.w"
else if (!(expo == 0 && mant == 0.0))
{
#line 414 "inform7/Chapter 12/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 386 "inform7/Chapter 12/Parse Literals.w"
;
int fbits = 0;
{
#line 426 "inform7/Chapter 12/Parse Literals.w"
fbits = (int) ((mant*8388608.0) + 0.5); /* round to nearest integer */
if (fbits >> 23) {
fbits = 0;
expo++; if (expo >= 255)
{
#line 435 "inform7/Chapter 12/Parse Literals.w"
return sign | 0x7f800000;
}
#line 429 "inform7/Chapter 12/Parse Literals.w"
;
}
}
#line 389 "inform7/Chapter 12/Parse Literals.w"
;
return (sign) | ((int)(expo << 23)) | (fbits);
}
#line 447 "inform7/Chapter 12/Parse Literals.w"
double 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 12/Constants and Descriptions.w"
int s_constant_value_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = MLD_0(VAL_NOTHING_ML);
#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 12/Constants and Descriptions.w"
verb_conjugation *vc = (verb_conjugation *) (RP[1]);
meaning_list *ml = Parser__SP__MeaningLists__new(LITERAL_ML);
specification *spec = verb_conjugation_to_verb_spec(vc);
spec->word_ref1 = w1; spec->word_ref2 = w2;
Parser__SP__MeaningLists__attach_spec(ml, spec);
*XP = ml;
}
#line 24 "inform7/Chapter 12/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 40 "inform7/Chapter 12/Constants and Descriptions.w"
MLD_1(VAL_RESPONSE_ML, RP[1]);
meaning_list *ml = (meaning_list *) (*XP);
Parser__SP__MeaningLists__set_score(ml, R[2]);
}
#line 25 "inform7/Chapter 12/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 12/Constants and Descriptions.w"
#line 55 "inform7/Chapter 12/Constants and Descriptions.w"
int s_miscellaneous_proper_noun_NTMR(int w1, int w2, int *X, void **XP) {
#line 56 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = Parser__SP__parse_excerpt(MISCELLANEOUS_MC, w1, w2);
if (ml) {
switch (Semantics__Nouns__ExcerptMeanings__get_secondary_code(
Parser__SP__MeaningLists__meaning(ml))) {
case ACTION_NAME_SMC:
case RELATION_SMC:
case RULE_SMC:
*XP = ml; return TRUE;
}
}
ml = Parser__SP__parse_excerpt(VARIABLE_MC, w1, w2);
if (ml) {
nonlocal_variable *nlv = RETRIEVE_POINTER_nonlocal_variable(
Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
if (Data__NonlocalVariables__is_constant(nlv)) {
*XP = ml; return TRUE;
}
}
if ((Text__Vocabulary__disjunction_of_flags(w1, w2)) & CONSTANT_VAL_BITMAP) {
ml = Parser__SP__parse_excerpt(CONSTANT_VAL_BITMAP, w1, w2);
if (ml) { *XP = ml; return TRUE; }
}
return FALSE;
}
#line 85 "inform7/Chapter 12/Constants and Descriptions.w"
int spec_named_constant_NTMR(int w1, int w2, int *X, void **XP) {
#line 86 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = Parser__SP__parse_excerpt(VARIABLE_MC, w1, w2);
if (ml) {
nonlocal_variable *nlv = RETRIEVE_POINTER_nonlocal_variable(
Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
if (Data__NonlocalVariables__is_constant(nlv)) {
*XP = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(nlv); return TRUE;
}
}
return FALSE;
}
#line 102 "inform7/Chapter 12/Constants and Descriptions.w"
int s_rulebook_outcome_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 103 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = Parser__SP__parse_excerpt(MISCELLANEOUS_MC, w1, w2);
if (ml) {
switch (Semantics__Nouns__ExcerptMeanings__get_secondary_code(
Parser__SP__MeaningLists__meaning(ml))) {
case RULE_OUTCOME_SMC: *XP = ml; return TRUE;
}
}
return FALSE;
}
int s_use_option_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 114 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = Parser__SP__parse_excerpt(MISCELLANEOUS_MC, w1, w2);
if (ml) {
switch (Semantics__Nouns__ExcerptMeanings__get_secondary_code(
Parser__SP__MeaningLists__meaning(ml))) {
case USE_OPTION_SMC: *XP = ml; return TRUE;
}
}
return FALSE;
}
int s_rule_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 125 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = Parser__SP__parse_excerpt(MISCELLANEOUS_MC, w1, w2);
if (ml) {
switch (Semantics__Nouns__ExcerptMeanings__get_secondary_code(
Parser__SP__MeaningLists__meaning(ml))) {
case RULE_SMC: *XP = ml; return TRUE;
}
}
return FALSE;
}
#line 141 "inform7/Chapter 12/Constants and Descriptions.w"
int s_table_column_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 142 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = Parser__SP__parse_excerpt(TABLE_COLUMN_MC, w1, w2);
if (ml) { *XP = ml; return TRUE; }
return FALSE;
}
#line 154 "inform7/Chapter 12/Constants and Descriptions.w"
int property_name_as_noun_phrase_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 157 "inform7/Chapter 12/Constants and Descriptions.w"
int s_property_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 159 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = Parser__SP__parse_excerpt(PROPERTY_MC, w1, w2);
if (ml) {
*XP = ml;
Parser__SP__MeaningLists__set_score(ml, FALSE);
if (parse_nt_against_word_range(property_name_as_noun_phrase_NTM, w1, w2, NULL, NULL)) Parser__SP__MeaningLists__set_score(ml, TRUE);
return TRUE;
}
return FALSE;
}
#line 190 "inform7/Chapter 12/Constants and Descriptions.w"
int s_adjective_list_as_desc_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLI_1(DC_ML, DC_ADJS_ML, 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 192 "inform7/Chapter 12/Constants and Descriptions.w"
#line 250 "inform7/Chapter 12/Constants and Descriptions.w"
int s_adjective_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = 0; *XP = make_adjlist(negate_adjlist(RP[2]), w1, w2);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = 0; *XP = make_adjlist(RP[2], w1, w2);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = 0; *XP = make_adjlist(RP[1], w1, w2);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 254 "inform7/Chapter 12/Constants and Descriptions.w"
int s_adjective_list_unarticled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = 0; *XP = 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 = join_adjlist(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 = 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 260 "inform7/Chapter 12/Constants and Descriptions.w"
#line 265 "inform7/Chapter 12/Constants and Descriptions.w"
int s_adjective_NTMR(int w1, int w2, int *X, void **XP) {
#line 266 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = Parser__SP__parse_excerpt_maximal(ADJECTIVE_MC, w1, w2);
if (ml) {
*XP = ml;
int sc = Parser__SP__MeaningLists__match_score(ml);
if (sc == 0) internal_error("Length-scored maximal parse with length 0");
return w1 + sc - 1;
}
return FALSE;
}
#line 293 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *join_adjlist(meaning_list *A, meaning_list *B) {
Parser__SP__MeaningLists__set_right(A, B);
return A;
}
meaning_list *make_adjlist(meaning_list *A, int w1, int w2) {
meaning_list *AL = Parser__SP__MeaningLists__new_with_words(AL_ML, w1, w2);
Parser__SP__MeaningLists__set_down(AL, A);
return AL;
}
meaning_list *negate_adjlist(meaning_list *A) {
meaning_list *L, *P, *R = NULL;
for (L = A, P = NULL; L; P = L, L = Parser__SP__MeaningLists__right(L)) {
meaning_list *N = Parser__SP__MeaningLists__right(L);
meaning_list *NEG = Parser__SP__MeaningLists__new(ADJ_NOT_ML);
if (R == NULL) R = NEG;
Parser__SP__MeaningLists__set_down(NEG, L);
if (P) Parser__SP__MeaningLists__set_right(P, NEG);
Parser__SP__MeaningLists__set_right(L, NULL);
Parser__SP__MeaningLists__set_right(NEG, N);
L = NEG;
}
return R;
}
#line 322 "inform7/Chapter 12/Constants and Descriptions.w"
int adjlist_applies_to_kind(meaning_list *A, kind *K) {
meaning_list *L;
if (A) A = Parser__SP__MeaningLists__down(A);
for (L = A; L; L = Parser__SP__MeaningLists__right(L)) {
meaning_list *ADJ = A;
if (Parser__SP__MeaningLists__production(ADJ) == ADJ_NOT_ML)
ADJ = Parser__SP__MeaningLists__down(ADJ);
if ((ADJ) && (Parser__SP__MeaningLists__production(ADJ) == ADJECTIVE_MC)) {
adjectival_phrase *aph = RETRIEVE_POINTER_adjectival_phrase(
Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ADJ)));
if (Semantics__Adjectives__Phrases__applicable_to(aph, K) == FALSE)
return FALSE;
} else return FALSE;
}
return TRUE;
}
#line 344 "inform7/Chapter 12/Constants and Descriptions.w"
kind *s_adj_domain = NULL;
#line 349 "inform7/Chapter 12/Constants and Descriptions.w"
parse_node *C12DefiniteCommonNoun_issued_at = NULL;
#line 365 "inform7/Chapter 12/Constants and Descriptions.w"
int s_qualifiable_noun_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = Parser__SP__MeaningLists__type_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 368 "inform7/Chapter 12/Constants and Descriptions.w"
int s_qualifiable_common_noun_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = Parser__SP__MeaningLists__type_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 371 "inform7/Chapter 12/Constants and Descriptions.w"
#line 376 "inform7/Chapter 12/Constants and Descriptions.w"
int s_instance_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 377 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = Parser__SP__parse_excerpt(NAMETAG_MC, w1, w2);
if (ml) { *XP = ml; return TRUE; }
return FALSE;
}
#line 390 "inform7/Chapter 12/Constants and Descriptions.w"
int s_applicable_adjective_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = RP[1]; if ((s_adj_domain) && (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 392 "inform7/Chapter 12/Constants and Descriptions.w"
#line 440 "inform7/Chapter 12/Constants and Descriptions.w"
int s_description_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_1(DC_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLD_1(DC_ML, 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 443 "inform7/Chapter 12/Constants and Descriptions.w"
int s_description_uncomposite_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 502 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = RP[1];
meaning_list *c = RP[2];
meaning_list *N = Parser__SP__MeaningLists__right(ml);
Parser__SP__MeaningLists__set_right(ml, c);
Parser__SP__MeaningLists__set_right(c, N);
*XP = ml;
}
#line 445 "inform7/Chapter 12/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 447 "inform7/Chapter 12/Constants and Descriptions.w"
int s_description_uncalled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 512 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = RP[2];
Parser__SP__MeaningLists__set_right(ml, RP[1]);
*XP = ml;
}
#line 449 "inform7/Chapter 12/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:
{
#line 492 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = RP[1];
meaning_list *nounpart = ml->child;
ml->child = RP[2];
ml->child->sibling = nounpart;
Parser__SP__MeaningLists__set_production(ml, DC_ADJSNOUN_ML);
*XP = ml;
}
#line 451 "inform7/Chapter 12/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 519 "inform7/Chapter 12/Constants and Descriptions.w"
*XP = RP[2];
if ((C12DefiniteCommonNoun_issued_at != current_sentence) ||
(C12DefiniteCommonNoun_issued_at == NULL)) {
C12DefiniteCommonNoun_issued_at = current_sentence;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C12DefiniteCommonNoun));
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 452 "inform7/Chapter 12/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = 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
default: *X = R[0]; break;
}
return TRUE;
}
#line 455 "inform7/Chapter 12/Constants and Descriptions.w"
int s_description_unspecified_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_1(DC_NOUN_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLD_2(DC_ADJSNOUN_ML, 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 459 "inform7/Chapter 12/Constants and Descriptions.w"
int s_common_description_unspecified_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_1(DC_NOUN_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLD_2(DC_ADJSNOUN_ML, 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 463 "inform7/Chapter 12/Constants and Descriptions.w"
#line 468 "inform7/Chapter 12/Constants and Descriptions.w"
int s_description_nounless_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_1(DC_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLD_1(DC_ML, 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 471 "inform7/Chapter 12/Constants and Descriptions.w"
int s_description_nounless_uncomposite_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 502 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = RP[1];
meaning_list *c = RP[2];
meaning_list *N = Parser__SP__MeaningLists__right(ml);
Parser__SP__MeaningLists__set_right(ml, c);
Parser__SP__MeaningLists__set_right(c, N);
*XP = ml;
}
#line 473 "inform7/Chapter 12/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 475 "inform7/Chapter 12/Constants and Descriptions.w"
int s_description_nounless_uncalled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 512 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = RP[2];
Parser__SP__MeaningLists__set_right(ml, RP[1]);
*XP = ml;
}
#line 477 "inform7/Chapter 12/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:
{
#line 492 "inform7/Chapter 12/Constants and Descriptions.w"
meaning_list *ml = RP[1];
meaning_list *nounpart = ml->child;
ml->child = RP[2];
ml->child->sibling = nounpart;
Parser__SP__MeaningLists__set_production(ml, DC_ADJSNOUN_ML);
*XP = ml;
}
#line 479 "inform7/Chapter 12/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 519 "inform7/Chapter 12/Constants and Descriptions.w"
*XP = RP[2];
if ((C12DefiniteCommonNoun_issued_at != current_sentence) ||
(C12DefiniteCommonNoun_issued_at == NULL)) {
C12DefiniteCommonNoun_issued_at = current_sentence;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C12DefiniteCommonNoun));
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 480 "inform7/Chapter 12/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = 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
default: *X = R[0]; break;
}
return TRUE;
}
#line 483 "inform7/Chapter 12/Constants and Descriptions.w"
int s_description_nounless_unspecified_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_1(DC_NOUN_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLD_2(DC_ADJSNOUN_ML, RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLD_1(DC_ADJS_ML, 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 488 "inform7/Chapter 12/Constants and Descriptions.w"
#line 548 "inform7/Chapter 12/Constants and Descriptions.w"
int s_calling_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = Parser__SP__MeaningLists__new_with_words(CALLED_ML, s_calling_name_NTM->range_result_w1[1], s_calling_name_NTM->range_result_w2[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Parser__SP__MeaningLists__new_with_words(CALLED_ML, s_calling_name_NTM->range_result_w1[1], s_calling_name_NTM->range_result_w2[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 551 "inform7/Chapter 12/Constants and Descriptions.w"
#line 565 "inform7/Chapter 12/Constants and Descriptions.w"
int s_specifier_NTMR(int w1, int w2, int *X, void **XP) {
#line 566 "inform7/Chapter 12/Constants and Descriptions.w"
int which_N = -1; quantifier *quantifier_used = NULL;
int x1 = Semantics__Quantifiers__parse_against_text(w1, w2, &which_N, &quantifier_used);
if (x1 >= 0) {
if ((x1<w2) && (Text__Languages__test_word(x1, article_NTM))) x1++;
*XP = Parser__SP__MeaningLists__determiner(quantifier_used, which_N, w1, x1-1);
return x1-1;
}
return 0;
}
#line 582 "inform7/Chapter 12/Constants and Descriptions.w"
int s_specifying_noun_NTMR(int w1, int w2, int *X, void **XP) {
#line 583 "inform7/Chapter 12/Constants and Descriptions.w"
int determiner_w1 = w1, determiner_w2 = w1;
quantifier *quantifier_used = NULL; kind *some_kind = NULL;
Config__Plugins__Call__parse_composite_NQs(&w1, &w2, &determiner_w1, &determiner_w2,
&quantifier_used, &some_kind);
if (some_kind) {
meaning_list *ml = Parser__SP__MeaningLists__new_with_words(DC_NOUN_ML, w1, w2);
ml->child = Parser__SP__MeaningLists__from_nametag(Kinds__get_nametag(some_kind));
ml->child->child = Parser__SP__MeaningLists__new(COMPOSITED_ML);
if (quantifier_used)
ml->sibling = Parser__SP__MeaningLists__determiner(quantifier_used, -1, determiner_w1, determiner_w2);
*XP = ml;
return w1-1;
}
return 0;
}
#line 635 "inform7/Chapter 12/Constants and Descriptions.w"
int s_nonkind_type_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 638 "inform7/Chapter 12/Constants and Descriptions.w"
int s_nonkind_type_unbracketed_NTMR(int w1, int w2, int *X, void **XP) {
#line 640 "inform7/Chapter 12/Constants and Descriptions.w"
if (Text__Vocabulary__test_flags(w1, KIND_FAST_MC)) {
int type_ID = Text__Vocabulary__get_literal_number_value(Text__word(w1));
if (type_ID > 1) {
*XP = Parser__SP__MeaningLists__type_from_ID(type_ID);
return TRUE;
}
if ((kind_parsing_mode != NORMAL_KIND_PARSING) && (type_ID < -1)) {
*XP = Parser__SP__MeaningLists__type_from_ID(-type_ID);
return TRUE;
}
}
return FALSE;
}
#line 61 "inform7/Chapter 12/Type Expressions and Values.w"
int s_type_expression_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 64 "inform7/Chapter 12/Type Expressions and Values.w"
int s_type_expression_unarticled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = MLD_1(TE_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = MLD_1(TE_ML, Parser__SP__MeaningLists__type_from_kind(RP[1]));
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = MLD_1(TE_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = MLD_1(TE_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = MLD_1(TE_ML, 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 73 "inform7/Chapter 12/Type Expressions and Values.w"
#line 87 "inform7/Chapter 12/Type Expressions and Values.w"
int s_descriptive_type_expression_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 90 "inform7/Chapter 12/Type Expressions and Values.w"
int s_descriptive_type_expression_unarticled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_1(TE_ML, 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 94 "inform7/Chapter 12/Type Expressions and Values.w"
#line 108 "inform7/Chapter 12/Type Expressions and Values.w"
int s_variable_scope_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLI_0(TE_ML, TE_EX_VAR_ML);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLI_1(TE_ML, TE_EX_VAR_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLI_0(TE_ML, TE_NEW_VAR_ML);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = MLI_1(TE_ML, TE_NEW_VAR_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = MLI_0(TE_ML, TE_GL_VAR_ML);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = MLI_1(TE_ML, TE_GL_VAR_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = MLI_1(TE_ML, TE_VAR_ML, 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 116 "inform7/Chapter 12/Type Expressions and Values.w"
#line 120 "inform7/Chapter 12/Type Expressions and Values.w"
int let_equation_mode = FALSE;
kind *probable_noun_phrase_context = NULL;
#line 136 "inform7/Chapter 12/Type Expressions and Values.w"
int if_let_equation_mode_NTMR(int w1, int w2, int *X, void **XP) {
#line 137 "inform7/Chapter 12/Type Expressions and Values.w"
if (let_equation_mode) return TRUE;
return FALSE;
}
#line 146 "inform7/Chapter 12/Type Expressions and Values.w"
int if_pronoun_present_NTMR(int w1, int w2, int *X, void **XP) {
#line 147 "inform7/Chapter 12/Type Expressions and Values.w"
if (Code__LocalVariables__is_possessive_form_of_it_enabled()) return TRUE;
return FALSE;
}
#line 156 "inform7/Chapter 12/Type Expressions and Values.w"
int if_table_column_expected_NTMR(int w1, int w2, int *X, void **XP) {
#line 157 "inform7/Chapter 12/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(int w1, int w2, int *X, void **XP) {
#line 163 "inform7/Chapter 12/Type Expressions and Values.w"
if (Kinds__get_construct(probable_noun_phrase_context) == CON_property)
return TRUE;
return FALSE;
}
#line 219 "inform7/Chapter 12/Type Expressions and Values.w"
int s_value_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = MLD_1(VAL_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLD_1(VAL_ML, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = MLD_1(VAL_ML, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = MLD_1(VAL_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 245 "inform7/Chapter 12/Type Expressions and Values.w"
meaning_list *ml = RP[1];
unsigned int p = Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(RP[1]));
if ((p != EQUATION_INLINE_ML) && (p != EQUATION_MC)) return FALSE;
MLI_2(VAL_ML, EQUATION_WHERE_ML, Parser__SP__MeaningLists__down(ml), RP[2]);
}
#line 225 "inform7/Chapter 12/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = MLI_1(VAL_ML, EQUATION_INLINE_ML, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = MLD_1(VAL_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *XP = MLD_1(VAL_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *XP = MLI_1(VAL_ML, VALUE_PHRASE_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10: *XP = MLD_1(VAL_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11: *XP = MLD_1(VAL_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12: *XP = MLD_1(VAL_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13: *XP = MLI_1(VAL_ML, MEMBER_OF_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14:
{
#line 253 "inform7/Chapter 12/Type Expressions and Values.w"
meaning_list *val = Parser__SP__MeaningLists__new(VAL_ML);
Parser__SP__MeaningLists__set_down(val, RP[1]);
MLI_1(VAL_ML, MEMBER_OF_ML, val);
}
#line 234 "inform7/Chapter 12/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15: *XP = MLI_2(VAL_ML, VAL_PROP_OF_ML, RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 16:
{
#line 260 "inform7/Chapter 12/Type Expressions and Values.w"
specification *lvspec =
Specifications__Storage__new_LOCAL_VARIABLE(-1, -1,
Code__LocalVariables__it_variable());
meaning_list *local = Parser__SP__MeaningLists__new(LOCAL_ML);
Parser__SP__MeaningLists__attach_spec(local, lvspec);
meaning_list *val = Parser__SP__MeaningLists__new(VAL_ML);
Parser__SP__MeaningLists__set_down(val, local);
MLI_2(VAL_ML, VAL_PROP_OF_ML, RP[3], val);
}
#line 236 "inform7/Chapter 12/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 17: *XP = MLI_2(VAL_ML, VAL_LIST_ENTRY_ML, RP[2], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 18: *XP = MLD_1(VAL_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 19: *XP = MLD_1(VAL_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 20: *XP = MLI_1(VAL_ML, VALUE_PHRASE_ML, 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 241 "inform7/Chapter 12/Type Expressions and Values.w"
#line 278 "inform7/Chapter 12/Type Expressions and Values.w"
int s_variable_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 283 "inform7/Chapter 12/Type Expressions and Values.w"
int s_nonglobal_variable_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = MLD_1(VAL_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLD_1(VAL_ML, 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 288 "inform7/Chapter 12/Type Expressions and Values.w"
int s_variable_as_value_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_1(VAL_ML, 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 291 "inform7/Chapter 12/Type Expressions and Values.w"
#line 295 "inform7/Chapter 12/Type Expressions and Values.w"
int s_local_variable_NTMR(int w1, int w2, int *X, void **XP) {
#line 296 "inform7/Chapter 12/Type Expressions and Values.w"
local_variable *lvar = Code__LocalVariables__parse(Code__Frames__current_stack_frame(), w1, w2);
if (lvar) {
specification *spec = Specifications__Storage__new_LOCAL_VARIABLE(-1, -1, lvar);
meaning_list *ml = Parser__SP__MeaningLists__new(LOCAL_ML);
Parser__SP__MeaningLists__attach_spec(ml, spec);
*XP = ml; return TRUE;
}
return FALSE;
}
#line 309 "inform7/Chapter 12/Type Expressions and Values.w"
int s_stacked_variable_NTMR(int w1, int w2, int *X, void **XP) {
#line 310 "inform7/Chapter 12/Type Expressions and Values.w"
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf == NULL) return FALSE;
stacked_variable *stv = Code__StackedVariables__Owners__Lists__parse(
Code__Frames__get_stvol(), w1, w2);
if (stv) {
meaning_list *ml = Parser__SP__MeaningLists__new(STV_ML);
specification *spec = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(
Code__StackedVariables__get_variable(stv));
Parser__SP__MeaningLists__attach_spec(ml, spec);
*XP = ml; return TRUE;
}
return FALSE;
}
#line 327 "inform7/Chapter 12/Type Expressions and Values.w"
int s_global_variable_NTMR(int w1, int w2, int *X, void **XP) {
#line 328 "inform7/Chapter 12/Type Expressions and Values.w"
meaning_list *ml = Parser__SP__parse_excerpt(VARIABLE_MC, w1, w2);
if (ml) { *XP = ml; return TRUE; }
return FALSE;
}
#line 338 "inform7/Chapter 12/Type Expressions and Values.w"
int property_of_shape_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 340 "inform7/Chapter 12/Type Expressions and Values.w"
#line 345 "inform7/Chapter 12/Type Expressions and Values.w"
vocabulary_entry *property_word_to_suppress = NULL;
#line 350 "inform7/Chapter 12/Type Expressions and Values.w"
int s_value_phrase_non_of_NTMR(int w1, int w2, int *X, void **XP) {
#line 351 "inform7/Chapter 12/Type Expressions and Values.w"
Text__Languages__remove_the(&w1, &w2);
vocabulary_entry *suppression = word_to_suppress_in_phrases;
if (parse_nt_against_word_range(property_of_shape_NTM, w1, w2, NULL, NULL)) {
if (property_word_to_suppress == NULL)
property_word_to_suppress = Text__Languages__word(property_of_shape_NTM, 0);
word_to_suppress_in_phrases = property_word_to_suppress;
}
meaning_list *ml = Parser__SP__parse_excerpt(VALUE_PHRASE_MC, w1, w2);
word_to_suppress_in_phrases = suppression;
if (ml) { *XP = ml; return TRUE; }
return FALSE;
}
int s_value_phrase_NTMR(int w1, int w2, int *X, void **XP) {
#line 365 "inform7/Chapter 12/Type Expressions and Values.w"
Text__Languages__remove_the(&w1, &w2);
meaning_list *ml = Parser__SP__parse_excerpt(VALUE_PHRASE_MC, w1, w2);
if (ml) { *XP = ml; return TRUE; }
return FALSE;
}
#line 387 "inform7/Chapter 12/Type Expressions and Values.w"
int s_table_reference_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLI_1(TR_ML, TR_ENTRY_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLI_3(TR_ML, TR_IN_ROW_ML, RP[1], RP[2], RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLI_2(TR_ML, TR_LISTED_IN_ML, RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = MLI_4(TR_ML, TR_CORR_ML, RP[1], RP[2], RP[3], RP[4]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = MLI_3(TR_ML, TR_OF_IN_ML, RP[1], RP[2], 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 393 "inform7/Chapter 12/Type Expressions and Values.w"
#line 399 "inform7/Chapter 12/Type Expressions and Values.w"
int s_action_pattern_as_value_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 405 "inform7/Chapter 12/Type Expressions and Values.w"
specification *as_noun = Specifications__Conditions__new_TEST_ACTION(RP[1]);
*XP = Parser__SP__MeaningLists__new(AP_ML);
Parser__SP__MeaningLists__attach_spec(*XP, as_noun);
}
#line 400 "inform7/Chapter 12/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 401 "inform7/Chapter 12/Type Expressions and Values.w"
#line 56 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_sentence_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_2(SV_ML, RP[1], RP[2]);
{
#line 85 "inform7/Chapter 12/Verbal and Relative Clauses.w"
if (Parser__SP__MeaningLists__production(
Parser__SP__MeaningLists__down(
Parser__SP__MeaningLists__down(
Parser__SP__MeaningLists__right(
Parser__SP__MeaningLists__down(RP[2]))))) != DC_ML)
return FAIL_NONTERMINAL;
}
#line 57 "inform7/Chapter 12/Verbal and Relative Clauses.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLD_2(SV_ML, RP[1], RP[2]); Parser__SP__correct_S_subtree_for_adjectives(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 59 "inform7/Chapter 12/Verbal and Relative Clauses.w"
#line 71 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_existential_np_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = 0; *XP = Parser__SP__MeaningLists__new(THERE_ML);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 73 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_existential_verb_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_2(VP_ML, Parser__SP__MeaningLists__verb(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 76 "inform7/Chapter 12/Verbal and Relative Clauses.w"
#line 119 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_general_verb_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = verb_ml_subtree(VP_ML, RP[1], RP[2], player_ml_subtree());
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = verb_ml_subtree(VP_ML, RP[1], RP[2], RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLD_2(VP_ML, Parser__SP__MeaningLists__verb(RP[1]), RP[2]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = MLD_2(VP_ML, Parser__SP__MeaningLists__verb(RP[1]), RP[2]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = MLD_2(VP_ML, Parser__SP__MeaningLists__verb(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 125 "inform7/Chapter 12/Verbal and Relative Clauses.w"
#line 137 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_universal_relation_term_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLI_2(VAL_ML, VAL_PAIR_ML, 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 139 "inform7/Chapter 12/Verbal and Relative Clauses.w"
#line 155 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_np_with_relative_clause_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_2(SN_ML, RP[1], RP[2]); Parser__SP__correct_S_subtree_for_adjectives(RP[1]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLD_2(SN_ML, RP[1], RP[2]); Parser__SP__correct_S_subtree_for_adjectives(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 158 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_implied_relative_verb_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = verb_ml_subtree(VP_ML, 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 = verb_ml_subtree(VP_ML, 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 162 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_relative_verb_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = verb_ml_subtree(VP_ML, RP[2], RP[3], player_ml_subtree());
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = verb_ml_subtree(VP_ML, RP[2], RP[3], RP[4]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLD_2(VP_ML, Parser__SP__MeaningLists__verb(RP[2]), RP[3]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = MLD_2(VP_ML, Parser__SP__MeaningLists__verb(RP[2]), RP[3]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = MLD_2(VP_ML, Parser__SP__MeaningLists__verb(RP[2]), 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 169 "inform7/Chapter 12/Verbal and Relative Clauses.w"
#line 174 "inform7/Chapter 12/Verbal and Relative Clauses.w"
meaning_list *verb_ml_subtree(unsigned int mc, verb_usage *vu, preposition_usage *pu, meaning_list *np) {
meaning_list *VP_part = Parser__SP__MeaningLists__new(mc);
Parser__SP__MeaningLists__set_down(VP_part, Parser__SP__MeaningLists__verb(vu));
Parser__SP__MeaningLists__set_down(
Parser__SP__MeaningLists__down(VP_part), Parser__SP__MeaningLists__preposition(pu));
Parser__SP__MeaningLists__set_right(Parser__SP__MeaningLists__down(VP_part), np);
return VP_part;
}
#line 188 "inform7/Chapter 12/Verbal and Relative Clauses.w"
meaning_list *player_ml_subtree(void) {
meaning_list *object_part = Parser__SP__MeaningLists__new(NP_ML);
meaning_list *val = Parser__SP__MeaningLists__new(VAL_ML);
meaning_list *var = Parser__SP__MeaningLists__new(VARIABLE_MC);
Parser__SP__MeaningLists__set_down(object_part, val);
Parser__SP__MeaningLists__set_down(val, var);
Parser__SP__MeaningLists__set_meaning(var, meaning_of_player);
return object_part;
}
#line 204 "inform7/Chapter 12/Verbal and Relative Clauses.w"
void Parser__SP__correct_S_subtree_for_adjectives(meaning_list *ml) {
meaning_list *subject_phrase_subtree, *object_phrase_subtree, *verb_phrase_subtree;
if (ml == NULL) internal_error("SV childless");
if ((Parser__SP__MeaningLists__right(ml) == NULL) && (Parser__SP__MeaningLists__production(ml) != DC_ML))
internal_error("SV with only one child, which isn't a DC");
subject_phrase_subtree = ml;
verb_phrase_subtree = Parser__SP__MeaningLists__right(ml);
if (Parser__SP__MeaningLists__down(verb_phrase_subtree) == NULL)
internal_error("SV childless");
if (Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(verb_phrase_subtree)) == NULL)
internal_error("SV only one child");
object_phrase_subtree = Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(verb_phrase_subtree));
{
#line 233 "inform7/Chapter 12/Verbal and Relative Clauses.w"
if ((Parser__SP__MeaningLists__down(object_phrase_subtree)) && (Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(object_phrase_subtree))) &&
(Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(object_phrase_subtree))) == NAMED_CONSTANT_MC) &&
(Parser__SP__MeaningLists__down(subject_phrase_subtree)) && (Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(subject_phrase_subtree))) &&
(Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(subject_phrase_subtree))) == DC_ML)) {
meaning_list *adjq = Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(object_phrase_subtree));
instance *I = RETRIEVE_POINTER_instance(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(adjq)));
if (Data__Instances__get_adjectival_phrase(I)) {
Parser__SP__MeaningLists__set_production(adjq, ADJECTIVE_MC);
Parser__SP__MeaningLists__set_meaning(adjq,
Semantics__Nouns__ExcerptMeanings__new(ADJECTIVE_MC, 0,
STORE_POINTER_adjectival_phrase(Data__Instances__get_adjectival_phrase(I))));
Parser__SP__MeaningLists__set_down(Parser__SP__MeaningLists__down(object_phrase_subtree),
Parser__SP__MeaningLists__new(DC_ML));
Parser__SP__MeaningLists__set_down(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(object_phrase_subtree)),
Parser__SP__MeaningLists__new(DC_ADJS_ML));
Parser__SP__MeaningLists__set_down(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(object_phrase_subtree))),
Parser__SP__MeaningLists__new(AL_ML));
Parser__SP__MeaningLists__set_down(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(object_phrase_subtree)))), adjq);
}
}
}
#line 221 "inform7/Chapter 12/Verbal and Relative Clauses.w"
;
if (Parser__SP__MeaningLists__production(verb_phrase_subtree) != VP_ML)
internal_error("SV not a VP");
if (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(verb_phrase_subtree)) != VERB_ML)
internal_error("child of SV not a verb");
}
#line 257 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int force_all_SP_noun_phrases_to_be_physical = FALSE;
#line 272 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_purely_physical_description_NTMR(int w1, int w2, int *X, void **XP) {
#line 273 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s = force_all_SP_noun_phrases_to_be_physical;
force_all_SP_noun_phrases_to_be_physical = TRUE;
meaning_list *ml = NULL;
if (parse_nt_against_word_range(s_description_NTM, w1, w2, NULL, NULL)) ml = most_recent_result_p;
force_all_SP_noun_phrases_to_be_physical = s;
if (ml) { *XP = ml; return TRUE; }
return FALSE;
}
int if_forced_physical_NTMR(int w1, int w2, int *X, void **XP) {
#line 283 "inform7/Chapter 12/Verbal and Relative Clauses.w"
if (force_all_SP_noun_phrases_to_be_physical) return TRUE;
return FALSE;
}
#line 293 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_noun_phrase_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_1(NP_ML, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLD_1(NP_ML, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLD_1(NP_ML, 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 297 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_noun_phrase_nounless_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_1(NP_ML, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLD_1(NP_ML, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLD_1(NP_ML, 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 302 "inform7/Chapter 12/Verbal and Relative Clauses.w"
#line 307 "inform7/Chapter 12/Verbal and Relative Clauses.w"
int s_descriptive_np_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 320 "inform7/Chapter 12/Verbal and Relative Clauses.w"
return FAIL_NONTERMINAL;
}
#line 309 "inform7/Chapter 12/Verbal and Relative Clauses.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 325 "inform7/Chapter 12/Verbal and Relative Clauses.w"
meaning_list *down_one = Parser__SP__MeaningLists__down(RP[1]);
if (Parser__SP__MeaningLists__production(down_one) == SN_ML) {
*XP = down_one;
} else {
MLD_1(SN_ML, RP[1]);
}
Parser__SP__MeaningLists__set_text(*XP, w1, w2);
}
#line 310 "inform7/Chapter 12/Verbal and Relative Clauses.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 325 "inform7/Chapter 12/Verbal and Relative Clauses.w"
meaning_list *down_one = Parser__SP__MeaningLists__down(RP[1]);
if (Parser__SP__MeaningLists__production(down_one) == SN_ML) {
*XP = down_one;
} else {
MLD_1(SN_ML, RP[1]);
}
Parser__SP__MeaningLists__set_text(*XP, w1, w2);
}
#line 311 "inform7/Chapter 12/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 312 "inform7/Chapter 12/Verbal and Relative Clauses.w"
#line 39 "inform7/Chapter 12/Conditions and Phrases.w"
int s_condition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = MLD_1(COND_ML, 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 42 "inform7/Chapter 12/Conditions and Phrases.w"
#line 48 "inform7/Chapter 12/Conditions and Phrases.w"
int s_condition_pure_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = MLI_2(COND_ML, COND_AND_ML, RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLI_2(COND_ML, COND_AND_ML, RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = MLI_2(COND_ML, COND_OR_ML, RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = MLI_2(COND_ML, COND_OR_ML, RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = MLD_1(COND_ML, 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 56 "inform7/Chapter 12/Conditions and Phrases.w"
#line 70 "inform7/Chapter 12/Conditions and Phrases.w"
int s_condition_with_chronology_NTMR(int w1, int w2, int *X, void **XP) {
#line 71 "inform7/Chapter 12/Conditions and Phrases.w"
time_period tp = Code__Chronology__TimePeriods__parse(w1, w2);
int end_of_non_time_part = Code__Chronology__TimePeriods__is_valid(&tp);
if ((end_of_non_time_part >= w1) &&
(parse_nt_against_word_range(s_condition_atomic_NTM, w1, end_of_non_time_part, NULL, NULL))) {
meaning_list *atomic_cnd = most_recent_result_p;
meaning_list *t = Parser__SP__MeaningLists__time(tp);
MLD_2(COND_PAST_ML, atomic_cnd, t);
return TRUE;
}
return FALSE;
}
#line 115 "inform7/Chapter 12/Conditions and Phrases.w"
int s_condition_atomic_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = MLI_1(COND_ML, COND_NOT_ML, 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 = MLD_1(COND_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = MLJ_1(COND_ML, COND_NOT_ML, COND_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = MLD_1(COND_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = MLJ_1(COND_ML, COND_NOT_ML, COND_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = MLD_1(COND_ML, 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 125 "inform7/Chapter 12/Conditions and Phrases.w"
#line 135 "inform7/Chapter 12/Conditions and Phrases.w"
int s_nonexistential_phrase_to_decide_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = MLI_1(COND_ML, COND_PHRASE_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLK_1(COND_ML, COND_NOT_ML, COND_ML, COND_PHRASE_ML, 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 12/Conditions and Phrases.w"
int s_existential_phrase_to_decide_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = MLI_1(COND_ML, COND_PHRASE_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLK_1(COND_ML, COND_NOT_ML, COND_ML, COND_PHRASE_ML, 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 12/Conditions and Phrases.w"
int existential_verb_phrase_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 147 "inform7/Chapter 12/Conditions and Phrases.w"
int s_phrase_to_decide_NTMR(int w1, int w2, int *X, void **XP) {
#line 149 "inform7/Chapter 12/Conditions and Phrases.w"
meaning_list *ml = Parser__SP__parse_excerpt(COND_PHRASE_MC, w1, w2);
if (ml) { *XP = ml; return TRUE; }
return FALSE;
}
#line 158 "inform7/Chapter 12/Conditions and Phrases.w"
int s_phrase_option_in_use_NTMR(int w1, int w2, int *X, void **XP) {
#line 159 "inform7/Chapter 12/Conditions and Phrases.w"
if (phrase_being_compiled) {
int i = Code__Routines__ToPhrases__parse_phrase_option_used(phrase_being_compiled, w1, w2);
if (i >= 0) {
MLD_1(COND_ML, Parser__SP__MeaningLists__option(i)); return TRUE;
}
}
return FALSE;
}
#line 176 "inform7/Chapter 12/Conditions and Phrases.w"
int s_action_pattern_as_condition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = Parser__SP__MeaningLists__action(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 178 "inform7/Chapter 12/Conditions and Phrases.w"
int s_action_pattern_as_negated_condition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = Parser__SP__MeaningLists__action(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 181 "inform7/Chapter 12/Conditions and Phrases.w"
#line 185 "inform7/Chapter 12/Conditions and Phrases.w"
int s_past_action_pattern_as_condition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 194 "inform7/Chapter 12/Conditions and Phrases.w"
action_pattern *ap = RP[1];
if (Plugins__Actions__Patterns__makes_callings(ap)) {
Problems__sentence_problem(_P_(C12PastActionCalled),
"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 = Parser__SP__MeaningLists__pastaction(ap);
}
#line 186 "inform7/Chapter 12/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 187 "inform7/Chapter 12/Conditions and Phrases.w"
int s_past_action_pattern_as_negated_condition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 194 "inform7/Chapter 12/Conditions and Phrases.w"
action_pattern *ap = RP[1];
if (Plugins__Actions__Patterns__makes_callings(ap)) {
Problems__sentence_problem(_P_(C12PastActionCalled),
"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 = Parser__SP__MeaningLists__pastaction(ap);
}
#line 189 "inform7/Chapter 12/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 190 "inform7/Chapter 12/Conditions and Phrases.w"
#line 226 "inform7/Chapter 12/Conditions and Phrases.w"
int s_command_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = MLI_0(CMD_ML, OTHERWISE_ML);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = NULL; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 241 "inform7/Chapter 12/Conditions and Phrases.w"
if (last_parsed_phrase_was_if == FALSE) return FAIL_NONTERMINAL; /* to force error */
return FALSE; /* to force failure of this production only */
}
#line 230 "inform7/Chapter 12/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 248 "inform7/Chapter 12/Conditions and Phrases.w"
if ((last_parsed_phrase_was_if) &&
(last_parsed_phrase_opened_a_block)) return FAIL_NONTERMINAL; /* to force error */
return FALSE; /* to force failure of this production only */
}
#line 231 "inform7/Chapter 12/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 255 "inform7/Chapter 12/Conditions and Phrases.w"
if (last_parsed_phrase_was_if == FALSE) return FAIL_NONTERMINAL; /* to force error */
if (last_parsed_phrase_opened_a_block) return FAIL_NONTERMINAL; /* to force error */
return FALSE; /* to force failure of this production only */
}
#line 232 "inform7/Chapter 12/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = MLI_0(CMD_ML, CASE_ML);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = MLI_1(CMD_ML, CASE_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *XP = MLD_1(CMD_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *XP = MLD_1(CMD_ML, 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 237 "inform7/Chapter 12/Conditions and Phrases.w"
#line 279 "inform7/Chapter 12/Conditions and Phrases.w"
int s_command_phrase_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLI_1(PHRASE_ML, INSTEAD_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = MLI_1(PHRASE_ML, INSTEAD_ML, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = MLD_1(PHRASE_ML, 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 283 "inform7/Chapter 12/Conditions and Phrases.w"
int s_command_phrase_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = MLD_1(SAY_ML, 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 287 "inform7/Chapter 12/Conditions and Phrases.w"
#line 292 "inform7/Chapter 12/Conditions and Phrases.w"
int s_to_phrase_NTMR(int w1, int w2, int *X, void **XP) {
#line 293 "inform7/Chapter 12/Conditions and Phrases.w"
meaning_list *ml = Parser__SP__parse_excerpt(VOID_PHRASE_MC + END_PHRASE_MC, w1, w2);
if (ml) { *XP = ml; return TRUE; }
return FALSE;
}
#line 302 "inform7/Chapter 12/Conditions and Phrases.w"
int s_say_phrase_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 330 "inform7/Chapter 12/Conditions and Phrases.w"
if (RP[2] == NULL) *XP = RP[1];
else if (RP[1] == NULL) *XP = RP[2];
else {
meaning_list *ml_last = RP[1];
while (Parser__SP__MeaningLists__right(ml_last))
ml_last = Parser__SP__MeaningLists__right(ml_last);
Parser__SP__MeaningLists__set_right(ml_last, RP[2]);
*XP = RP[1];
}
}
#line 303 "inform7/Chapter 12/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 366 "inform7/Chapter 12/Conditions and Phrases.w"
int lw1, lw2; char *p = Text__word_raw_text(w1);
{
#line 412 "inform7/Chapter 12/Conditions and Phrases.w"
int k, sqb = 0;
for (k=0; p[k]; k++) {
switch (p[k]) {
case '[': sqb++; if (sqb > 1)
{
#line 448 "inform7/Chapter 12/Conditions and Phrases.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__sentence_problem(_P_(C12NestedUSubstitution),
"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__sentence_problem(_P_(C12NestedSubstitution),
"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 FALSE;
}
#line 415 "inform7/Chapter 12/Conditions and Phrases.w"
; break;
case ']': sqb--; if (sqb < 0)
{
#line 482 "inform7/Chapter 12/Conditions and Phrases.w"
it_is_not_worth_adding = TRUE;
Problems__sentence_problem(_P_(C12UnopenedSubstitution),
"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 FALSE;
}
#line 416 "inform7/Chapter 12/Conditions and Phrases.w"
; break;
case ':': if ((k>0) && (isdigit(p[k-1])) && (isdigit(p[k+1]))) break;
case ';':
if (sqb > 0)
{
#line 390 "inform7/Chapter 12/Conditions and Phrases.w"
it_is_not_worth_adding = TRUE;
Problems__sentence_problem(_P_(C12TSWithPunctuation),
"a substitution contains a '.', ':' or ';'",
"which suggests that a close square bracket ']' may have gone astray.");
it_is_not_worth_adding = FALSE;
return FALSE;
}
#line 419 "inform7/Chapter 12/Conditions and Phrases.w"
;
break;
case ',':
if (sqb > 0)
{
#line 431 "inform7/Chapter 12/Conditions and Phrases.w"
it_is_not_worth_adding = TRUE;
Problems__sentence_problem(_P_(C12TSWithComma),
"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 FALSE;
}
#line 422 "inform7/Chapter 12/Conditions and Phrases.w"
;
break;
}
}
if (sqb != 0)
{
#line 470 "inform7/Chapter 12/Conditions and Phrases.w"
it_is_not_worth_adding = TRUE;
Problems__sentence_problem(_P_(C12UnclosedSubstitution),
"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 FALSE;
}
#line 426 "inform7/Chapter 12/Conditions and Phrases.w"
;
}
#line 367 "inform7/Chapter 12/Conditions and Phrases.w"
;
lw1 = lexer_wordcount;
Text__feed_into_lexer(p, TRUE, NULL); /* expand unquoted text substitution */
lw2 = lexer_wordcount - 1;
Text__feed_into_lexer(" . ", FALSE, NULL);
if (parse_nt_against_word_range(s_unpacked_text_with_substitutions_NTM, lw1, lw2, NULL, NULL)) { *XP = most_recent_result_p; return TRUE; }
return FALSE;
}
#line 304 "inform7/Chapter 12/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = Parser__SP__MeaningLists__say_verb(RP[1], R[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = Parser__SP__MeaningLists__say_adjective(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = Parser__SP__MeaningLists__say_verb(RP[1], R[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 380 "inform7/Chapter 12/Conditions and Phrases.w"
int neg = FALSE;
if ((R[1]) || (R[2])) neg = TRUE;
meaning_list *vml = Parser__SP__MeaningLists__say_verb(RP[2], neg);
meaning_list *aml = Parser__SP__MeaningLists__say_modal_verb(RP[1]);
vml->child = aml;
*XP = vml;
}
#line 308 "inform7/Chapter 12/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 380 "inform7/Chapter 12/Conditions and Phrases.w"
int neg = FALSE;
if ((R[1]) || (R[2])) neg = TRUE;
meaning_list *vml = Parser__SP__MeaningLists__say_verb(RP[2], neg);
meaning_list *aml = Parser__SP__MeaningLists__say_modal_verb(RP[1]);
vml->child = aml;
*XP = vml;
}
#line 309 "inform7/Chapter 12/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = Parser__SP__MeaningLists__say_adjective(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 312 "inform7/Chapter 12/Conditions and Phrases.w"
int s_say_term_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = 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
default: *X = R[0]; break;
}
return TRUE;
}
#line 316 "inform7/Chapter 12/Conditions and Phrases.w"
int s_text_substitution_NTMR(int w1, int w2, int *X, void **XP) {
#line 318 "inform7/Chapter 12/Conditions and Phrases.w"
meaning_list *ml = Parser__SP__parse_excerpt(SAY_PHRASE_MC, w1, w2);
if (ml) { *XP = ml; return TRUE; }
return FALSE;
}
#line 356 "inform7/Chapter 12/Conditions and Phrases.w"
int s_unpacked_text_with_substitutions_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 390 "inform7/Chapter 12/Conditions and Phrases.w"
it_is_not_worth_adding = TRUE;
Problems__sentence_problem(_P_(C12TSWithPunctuation),
"a substitution contains a '.', ':' or ';'",
"which suggests that a close square bracket ']' may have gone astray.");
it_is_not_worth_adding = FALSE;
return FALSE;
}
#line 357 "inform7/Chapter 12/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 400 "inform7/Chapter 12/Conditions and Phrases.w"
it_is_not_worth_adding = TRUE;
Problems__sentence_problem(_P_(C12EmptySubstitution),
"the text here contains an empty substitution '[]'",
"which is not allowed. To say nothing - well, say nothing.");
it_is_not_worth_adding = FALSE;
return FALSE;
}
#line 358 "inform7/Chapter 12/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 400 "inform7/Chapter 12/Conditions and Phrases.w"
it_is_not_worth_adding = TRUE;
Problems__sentence_problem(_P_(C12EmptySubstitution),
"the text here contains an empty substitution '[]'",
"which is not allowed. To say nothing - well, say nothing.");
it_is_not_worth_adding = FALSE;
return FALSE;
}
#line 359 "inform7/Chapter 12/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 400 "inform7/Chapter 12/Conditions and Phrases.w"
it_is_not_worth_adding = TRUE;
Problems__sentence_problem(_P_(C12EmptySubstitution),
"the text here contains an empty substitution '[]'",
"which is not allowed. To say nothing - well, say nothing.");
it_is_not_worth_adding = FALSE;
return FALSE;
}
#line 360 "inform7/Chapter 12/Conditions and Phrases.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
default: *X = R[0]; break;
}
return TRUE;
}
#line 362 "inform7/Chapter 12/Conditions and Phrases.w"
#line 93 "inform7/Chapter 12/Meaning List Conversions.w"
int PHRASE_subtree_to_type_nesting = 0;
specification *Parser__SP__Conversion__CMD_subtree_to_spec(meaning_list *ml) {
if (ml == NULL) return Specifications__Unknown__new(-1, -1);
NOW_CONVERTING_SUBTREE(CMD_ML);
PHRASE_subtree_to_type_nesting++;
if (PHRASE_subtree_to_type_nesting == 1) {
int w1, w2;
Parser__SP__MeaningLists__get_text(ml, &w1, &w2);
last_parsed_phrase_was_if = FALSE;
last_parsed_phrase_opened_a_block = FALSE;
if ((parse_nt_against_word_range(control_structure_phrase_NTM, w1, w2, NULL, NULL)) &&
((most_recent_result_p == if_CSP) || (most_recent_result_p == switch_CSP)))
last_parsed_phrase_was_if = TRUE;
if (parse_nt_against_word_range(phrase_beginning_block_NTM, w1, w2, NULL, NULL)) last_parsed_phrase_opened_a_block = TRUE;
LOGIF(MATCHING, "Setting LPPWI to %d\n", last_parsed_phrase_was_if);
}
ml = Parser__SP__MeaningLists__down(ml);
switch(Parser__SP__MeaningLists__production(ml)) {
case PHRASE_ML: spec = PHRASE_subtree_to_spec(ml); break;
case OTHERWISE_ML: spec = OTHERWISE_subtree_to_spec(ml); break;
case CASE_ML: spec = CASE_subtree_to_spec(ml); break;
case MISCELLANEOUS_MC:
switch(Semantics__Nouns__ExcerptMeanings__get_secondary_code(Parser__SP__MeaningLists__meaning(ml))) {
case RULE_OUTCOME_SMC: spec = RULE_OUTCOME_SMC_to_spec(ml, FALSE); break;
default: CHILD_UNCONVERTIBLE(VAL_ML);
}
break;
default: CHILD_UNCONVERTIBLE(CMD_ML);
}
PHRASE_subtree_to_type_nesting--;
return spec;
}
#line 130 "inform7/Chapter 12/Meaning List Conversions.w"
specification *Parser__SP__Conversion__COND_subtree_to_spec(meaning_list *ml) {
if (ml == NULL) return Specifications__Unknown__new(-1, -1);
NOW_CONVERTING_SUBTREE(COND_ML);
int mw1, mw2; Parser__SP__MeaningLists__get_text(ml, &mw1, &mw2);
ml = Parser__SP__MeaningLists__down(ml);
switch(Parser__SP__MeaningLists__production(ml)) {
case COND_NOT_ML: spec = COND_NOT_subtree_to_spec(ml); break;
case COND_AND_ML: spec = COND_AND_subtree_to_spec(ml); break;
case COND_OR_ML: spec = COND_OR_subtree_to_spec(ml); break;
case COND_PAST_ML: spec = COND_PAST_subtree_to_spec(ml); break;
case OPTION_ML: spec = OPTION_subtree_to_spec(ml); break;
case PHRASE_ML: spec = PHRASE_subtree_to_spec(ml); break;
case COND_PHRASE_ML: spec = COND_PHRASE_subtree_to_spec(ml); break;
case ACTION_ML: spec = ACTION_subtree_to_spec(ml); break;
case SN_ML: spec = SN_subtree_to_spec(ml); break;
case SV_ML: spec = SV_subtree_to_spec(ml); break;
default: CHILD_UNCONVERTIBLE(COND_ML);
}
if ((mw1 >= 0) && (spec->word_ref1 < 0)) { spec->word_ref1 = mw1; spec->word_ref2 = mw2; }
return spec;
}
#line 158 "inform7/Chapter 12/Meaning List Conversions.w"
specification *Parser__SP__Conversion__TE_subtree_to_spec(meaning_list *ml) {
if (ml == NULL) return Specifications__Unknown__new(-1, -1); /* note that no problem message is issued */
NOW_CONVERTING_SUBTREE(TE_ML);
int mw1, mw2; Parser__SP__MeaningLists__get_text(ml, &mw1, &mw2);
ml = Parser__SP__MeaningLists__down(ml);
switch(Parser__SP__MeaningLists__production(ml)) {
case TE_CALLED_ML:
spec = TE_CALLED_subtree_to_spec(ml); break;
case TE_EX_VAR_ML:
spec = TE_EX_VAR_subtree_to_spec(ml); break;
case TE_NEW_VAR_ML:
spec = TE_NEW_VAR_subtree_to_spec(ml); break;
case TE_GL_VAR_ML:
spec = TE_GL_VAR_subtree_to_spec(ml); break;
case TE_VAR_ML:
spec = TE_VAR_subtree_to_spec(ml); break;
case DC_ML: spec = Parser__SP__Conversion__DC_subtree_to_spec(ml, FALSE); break;
case VAL_NOTHING_ML: spec = VAL_NOTHING_subtree_to_spec(ml); break;
case VAL_RESPONSE_ML: spec = VAL_RESPONSE_subtree_to_spec(ml); break;
case LITERAL_ML: spec = LITERAL_subtree_to_spec(ml); break;
case TYPE_ML: spec = TYPE_subtree_to_spec(ml); break;
case NAMED_CONSTANT_MC: spec = NAMED_CONSTANT_MC_to_spec(ml); break;
case RULE_MC: spec = RULE_MC_to_spec(ml); break;
case RULEBOOK_MC: spec = RULEBOOK_MC_to_spec(ml); break;
case ACTIVITY_MC: spec = ACTIVITY_MC_to_spec(ml); break;
case EQUATION_MC: spec = EQUATION_MC_to_spec(ml); break;
case PHRASE_CONSTANT_MC: spec = PHRASE_CONSTANT_MC_to_spec(ml); break;
case TABLE_MC: spec = TABLE_MC_to_spec(ml); break;
case VARIABLE_MC: spec = VARIABLE_MC_to_spec(ml); break;
case MISCELLANEOUS_MC:
switch(Semantics__Nouns__ExcerptMeanings__get_secondary_code(Parser__SP__MeaningLists__meaning(ml))) {
case ACTION_NAME_SMC: spec = ACTION_NAME_SMC_to_spec(ml); break;
case RELATION_SMC: spec = RELATION_SMC_to_spec(ml); break;
case RULE_OUTCOME_SMC: spec = RULE_OUTCOME_SMC_to_spec(ml, TRUE); break;
case USE_OPTION_SMC: spec = USE_OPTION_SMC_to_spec(ml); break;
case RULE_SMC: spec = RULE_SMC_to_spec(ml); break;
default: CHILD_UNCONVERTIBLE(VAL_ML);
}
break;
default: CHILD_UNCONVERTIBLE(TE_ML);
}
if ((mw1 >= 0) && (spec->word_ref1 < 0)) { spec->word_ref1 = mw1; spec->word_ref2 = mw2; }
return spec;
}
#line 212 "inform7/Chapter 12/Meaning List Conversions.w"
specification *Parser__SP__Conversion__VAL_subtree_to_spec(meaning_list *ml) {
if (ml == NULL) return Specifications__Unknown__new(-1, -1);
NOW_CONVERTING_SUBTREE(VAL_ML);
int mw1, mw2; Parser__SP__MeaningLists__get_text(ml, &mw1, &mw2);
ml = Parser__SP__MeaningLists__down(ml);
switch(Parser__SP__MeaningLists__production(ml)) {
case AP_ML: spec = AP_subtree_to_spec(ml); break;
case DC_ML: spec = Parser__SP__Conversion__DC_subtree_to_spec(ml, TRUE); break;
case LITERAL_ML: spec = LITERAL_subtree_to_spec(ml); break;
case LOCAL_ML: spec = LOCAL_subtree_to_spec(ml); break;
case MEMBER_OF_ML: spec = MEMBER_OF_subtree_to_spec(ml); break;
case STV_ML: spec = STV_subtree_to_spec(ml); break;
case TR_ML: spec = TR_subtree_to_spec(ml); break;
case VAL_LIST_ENTRY_ML: spec = VAL_LIST_ENTRY_subtree_to_spec(ml); break;
case VAL_NOTHING_ML: spec = VAL_NOTHING_subtree_to_spec(ml); break;
case VAL_RESPONSE_ML: spec = VAL_RESPONSE_subtree_to_spec(ml); break;
case VAL_PAIR_ML: spec = VAL_PAIR_subtree_to_spec(ml); break;
case VAL_PROP_OF_ML: spec = VAL_PROP_OF_subtree_to_spec(ml); break;
case VALUE_PHRASE_ML: spec = VALUE_PHRASE_subtree_to_spec(ml); break;
case EQUATION_INLINE_ML: spec = EQUATION_MC_to_spec(Parser__SP__MeaningLists__down(ml)); break;
case EQUATION_WHERE_ML: spec = EQUATION_MC_to_spec(Parser__SP__MeaningLists__down(ml)); break;
case ACTIVITY_MC: spec = ACTIVITY_MC_to_spec(ml); break;
case EQUATION_MC: spec = EQUATION_MC_to_spec(ml); break;
case PROPERTY_MC: spec = PROPERTY_MC_to_spec(ml); break;
case PHRASE_CONSTANT_MC: spec = PHRASE_CONSTANT_MC_to_spec(ml); break;
case NAMED_CONSTANT_MC: spec = NAMED_CONSTANT_MC_to_spec(ml); break;
case RULE_MC: spec = RULE_MC_to_spec(ml); break;
case RULEBOOK_MC: spec = RULEBOOK_MC_to_spec(ml); break;
case TABLE_COLUMN_MC: spec = TABLE_COLUMN_MC_to_spec(ml); break;
case TABLE_MC: spec = TABLE_MC_to_spec(ml); break;
case VARIABLE_MC: spec = VARIABLE_MC_to_spec(ml); break;
case NAMETAG_MC: spec = NAMETAG_MC_to_spec(ml); break;
case MISCELLANEOUS_MC:
switch(Semantics__Nouns__ExcerptMeanings__get_secondary_code(Parser__SP__MeaningLists__meaning(ml))) {
case ACTION_NAME_SMC: spec = ACTION_NAME_SMC_to_spec(ml); break;
case RELATION_SMC: spec = RELATION_SMC_to_spec(ml); break;
case RULE_OUTCOME_SMC: spec = RULE_OUTCOME_SMC_to_spec(ml, TRUE); break;
case USE_OPTION_SMC: spec = USE_OPTION_SMC_to_spec(ml); break;
case RULE_SMC: spec = RULE_SMC_to_spec(ml); break;
default: CHILD_UNCONVERTIBLE(VAL_ML);
}
break;
default: CHILD_UNCONVERTIBLE(VAL_ML);
}
if ((mw1 >= 0) && (spec->word_ref1 < 0)) { spec->word_ref1 = mw1; spec->word_ref2 = mw2; }
return spec;
}
#line 272 "inform7/Chapter 12/Meaning List Conversions.w"
specification *ACTION_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(ACTION_ML);
spec = Parser__SP__MeaningLists__get_attached_spec(ml);
return spec;
}
#line 281 "inform7/Chapter 12/Meaning List Conversions.w"
specification *AP_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(AP_ML);
spec = Parser__SP__MeaningLists__get_attached_spec(ml);
return spec;
}
#line 290 "inform7/Chapter 12/Meaning List Conversions.w"
specification *CASE_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING(CASE_ML);
ml = Parser__SP__MeaningLists__down(ml);
if (ml == NULL) spec = Specifications__Commands__new_default_CASE();
else switch(Parser__SP__MeaningLists__production(ml)) {
case VAL_ML: {
specification *case_value = Parser__SP__Conversion__VAL_subtree_to_spec(ml);
spec = Specifications__Commands__new_CASE(case_value); break;
}
default: CHILD_UNCONVERTIBLE(CASE_ML);
}
return spec;
}
#line 307 "inform7/Chapter 12/Meaning List Conversions.w"
specification *COND_AND_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(COND_AND_ML);
spec = Specifications__Conditions__new_LOGICAL_AND(
Parser__SP__Conversion__COND_subtree_to_spec(Parser__SP__MeaningLists__down(ml)),
Parser__SP__Conversion__COND_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml))));
return spec;
}
#line 318 "inform7/Chapter 12/Meaning List Conversions.w"
specification *COND_OR_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(COND_OR_ML);
spec = Specifications__Conditions__new_LOGICAL_OR(
Parser__SP__Conversion__COND_subtree_to_spec(Parser__SP__MeaningLists__down(ml)),
Parser__SP__Conversion__COND_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml))));
return spec;
}
#line 329 "inform7/Chapter 12/Meaning List Conversions.w"
specification *COND_NOT_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(COND_NOT_ML);
spec = Parser__SP__Conversion__COND_subtree_to_spec(Parser__SP__MeaningLists__down(ml));
if (Specifications__test_flag(spec, CONDITION_NEGATED_SPFLAG))
Specifications__clear_flag(spec, CONDITION_NEGATED_SPFLAG);
else
Specifications__set_flag(spec, CONDITION_NEGATED_SPFLAG);
return spec;
}
#line 342 "inform7/Chapter 12/Meaning List Conversions.w"
specification *COND_PAST_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(COND_PAST_ML);
spec = Parser__SP__Conversion__COND_subtree_to_spec(Parser__SP__MeaningLists__down(ml));
int tense_only = IS_TENSE;
if (Specifications__get_condition_tense(spec)) tense_only = Code__Chronology__TimePeriods__get_tense(Specifications__get_condition_tense(spec));
Specifications__set_condition_tense(spec,
Specifications__get_condition_tense(Parser__SP__MeaningLists__get_attached_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)))));
Code__Chronology__TimePeriods__set_tense(Specifications__get_condition_tense(spec), tense_only);
return spec;
}
#line 356 "inform7/Chapter 12/Meaning List Conversions.w"
specification *COND_PHRASE_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING(COND_PHRASE_ML);
spec = general_phrase_to_spec(ml);
return spec;
}
#line 366 "inform7/Chapter 12/Meaning List Conversions.w"
parse_node *C5SpecificCalling_last_issued = NULL;
specification *Parser__SP__Conversion__DC_subtree_to_spec(meaning_list *ml, int construed_as_noun) {
NOW_CONVERTING_SUBTREE(DC_ML);
meaning_list *annotation;
ml = Parser__SP__MeaningLists__down(ml);
switch(Parser__SP__MeaningLists__production(ml)) {
case SN_ML: spec = SN_subtree_to_spec(ml); break;
case DC_ADJS_ML: spec = DC_ADJS_subtree_to_spec(ml, construed_as_noun); break;
case DC_NOUN_ML: spec = DC_NOUN_subtree_to_spec(ml); break;
case DC_ADJSNOUN_ML: spec = DC_ADJSNOUN_subtree_to_spec(ml); break;
default: CHILD_UNCONVERTIBLE(DC_ML);
}
if (spec->word_ref1 < 0) {
int w1 = -1, w2 = -1;
Parser__SP__MeaningLists__get_text(ml, &w1, &w2);
spec->word_ref1 = w1; spec->word_ref2 = w2;
}
annotation = Parser__SP__MeaningLists__right(ml);
while (annotation) {
switch (Parser__SP__MeaningLists__production(annotation)) {
case CALLED_ML:
if (Specifications__Values__is_actual_CONSTANT(spec)) {
if (C5SpecificCalling_last_issued != current_sentence) {
C5SpecificCalling_last_issued = current_sentence;
Problems__sentence_problem(_P_(C12SpecificCalling),
"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 (Code__Frames__current_stack_frame()) {
int c1, c2;
Parser__SP__MeaningLists__get_text(annotation, &c1, &c2);
Specifications__Conditions__attach_calling(spec, c1, c2);
kind *K = Specifications__Conditions__get_described_kind(spec);
if (Specifications__Values__is_generic_CONSTANT(spec)) K = Specifications__get_kind(spec);
Code__LocalVariables__ensure_called_local(c1, c2, K);
}
}
break;
case DETERMINER_ML:
{
#line 430 "inform7/Chapter 12/Meaning List Conversions.w"
quantifier *quant = RETRIEVE_POINTER_quantifier(
Parser__SP__MeaningLists__get_attached_data(annotation));
if (Specifications__species_is(spec, DESCRIPTION_SPC))
Specifications__Conditions__attach_quantifier(spec,
quant, Parser__SP__MeaningLists__match_score(annotation));
else if (!((quant == exists_quantifier) &&
(Specifications__Values__is_actual_CONSTANT(spec))))
Specifications__Unknown__coerce(spec);
}
#line 415 "inform7/Chapter 12/Meaning List Conversions.w"
;
break;
default: CHILD_UNCONVERTIBLE(DC_ML);
}
annotation = Parser__SP__MeaningLists__right(annotation);
}
return spec;
}
#line 442 "inform7/Chapter 12/Meaning List Conversions.w"
specification *DC_ADJS_subtree_to_spec(meaning_list *ml, int construed_as_noun) {
NOW_CONVERTING_SUBTREE(DC_ADJS_ML);
if ((Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(ml))) == NULL) && (construed_as_noun)) {
adjective_list_entry *tr = adj_to_adjective_list_entry(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(ml)));
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(tr);
property *prn = NULL;
if (Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(aph))
prn = Kinds__get_coinciding_property(Data__Instances__kind(
Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(aph)));
else if (Semantics__Adjectives__Phrases__has_EORP_meaning(aph))
prn = Semantics__Adjectives__Phrases__has_EORP_meaning(aph);
if (prn){
spec = Properties__to_specification(prn);
return spec;
}
}
spec = qualified_noun_to_spec(Parser__SP__MeaningLists__down(ml), NULL);
return spec;
}
#line 465 "inform7/Chapter 12/Meaning List Conversions.w"
specification *DC_NOUN_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(DC_NOUN_ML);
spec = qualified_noun_to_spec(NULL, Parser__SP__MeaningLists__down(ml));
return spec;
}
#line 474 "inform7/Chapter 12/Meaning List Conversions.w"
specification *DC_ADJSNOUN_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(DC_ADJSNOUN_ML);
spec = qualified_noun_to_spec(Parser__SP__MeaningLists__down(ml), Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)));
return spec;
}
#line 483 "inform7/Chapter 12/Meaning List Conversions.w"
specification *LITERAL_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(LITERAL_ML);
spec = Parser__SP__MeaningLists__get_attached_spec(ml);
return spec;
}
#line 492 "inform7/Chapter 12/Meaning List Conversions.w"
specification *LOCAL_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(LOCAL_ML);
spec = Parser__SP__MeaningLists__get_attached_spec(ml);
return spec;
}
#line 501 "inform7/Chapter 12/Meaning List Conversions.w"
specification *MEMBER_OF_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(MEMBER_OF_ML);
spec = NP_subtree_to_spec(Parser__SP__MeaningLists__down(ml));
if (Specifications__Storage__get_storage_form(spec) == LOCAL_VARIABLE_SPC) return spec;
if (Specifications__species_is(spec, DESCRIPTION_SPC) == FALSE) {
LOG("Error on: $X", spec);
internal_error("Unexpected member-of");
}
return spec;
}
#line 516 "inform7/Chapter 12/Meaning List Conversions.w"
specification *NP_subtree_to_spec(meaning_list *ml) {
if (ml == NULL) internal_error("missing NP");
RECORD_MLC_BACKTRACE;
specification *spec = NULL;
if (Parser__SP__MeaningLists__production(ml) == NP_ML)
ml = Parser__SP__MeaningLists__down(ml);
switch(Parser__SP__MeaningLists__production(ml)) {
case DC_ML: spec = Parser__SP__Conversion__DC_subtree_to_spec(ml, FALSE); break;
case VAL_ML: spec = Parser__SP__Conversion__VAL_subtree_to_spec(ml); break;
default: LOG("Offending subtree:\n$m", ml); internal_error("Non-NP production");
}
return spec;
}
#line 533 "inform7/Chapter 12/Meaning List Conversions.w"
specification *OPTION_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(OPTION_ML);
spec = Parser__SP__MeaningLists__get_attached_spec(ml);
return spec;
}
#line 542 "inform7/Chapter 12/Meaning List Conversions.w"
specification *OTHERWISE_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(OTHERWISE_ML);
spec = Specifications__Commands__new_OTHERWISE();
return spec;
}
#line 551 "inform7/Chapter 12/Meaning List Conversions.w"
specification *PHRASE_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING(PHRASE_ML);
spec = general_phrase_to_spec(ml);
return spec;
}
#line 560 "inform7/Chapter 12/Meaning List Conversions.w"
specification *SN_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(SN_ML);
spec = general_sentence_to_spec(ml);
return spec;
}
#line 569 "inform7/Chapter 12/Meaning List Conversions.w"
specification *STV_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(STV_ML);
spec = Parser__SP__MeaningLists__get_attached_spec(ml);
return spec;
}
#line 578 "inform7/Chapter 12/Meaning List Conversions.w"
specification *SV_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(SV_ML);
spec = general_sentence_to_spec(ml);
return spec;
}
#line 587 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TE_CALLED_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(TE_CALLED_ML);
spec = Parser__SP__Conversion__TE_subtree_to_spec(Parser__SP__MeaningLists__down(ml));
if (Specifications__is_UNKNOWN(spec)) return spec;
int c1, c2;
Parser__SP__MeaningLists__get_text(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)), &c1, &c2);
Specifications__Conditions__attach_calling(spec, c1, c2);
return spec;
}
#line 600 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TE_EX_VAR_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING(TE_EX_VAR_ML);
kind *K = police_te(Parser__SP__MeaningLists__down(ml));
spec = Specifications__Storage__new_generic_LOCAL_VARIABLE(K);
return spec;
}
#line 610 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TE_GL_VAR_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING(TE_GL_VAR_ML);
police_te(Parser__SP__MeaningLists__down(ml));
spec = Specifications__Storage__new_generic_NONLOCAL_VARIABLE(NULL);
return spec;
}
#line 620 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TE_NEW_VAR_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING(TE_NEW_VAR_ML);
kind *K = police_te(Parser__SP__MeaningLists__down(ml));
spec = Specifications__Matching__new_NEW_LOCAL_VARIABLE_NAME(K);
return spec;
}
#line 630 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TE_VAR_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING(TE_VAR_ML);
kind *K = police_te(Parser__SP__MeaningLists__down(ml));
spec = Specifications__Storage__new_generic_NONLOCAL_VARIABLE(K);
return spec;
}
#line 640 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TR_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(TR_ML);
ml = Parser__SP__MeaningLists__down(ml);
switch(Parser__SP__MeaningLists__production(ml)) {
case TR_ENTRY_ML: spec = TR_ENTRY_subtree_to_spec(ml); break;
case TR_IN_ROW_ML: spec = TR_IN_ROW_subtree_to_spec(ml); break;
case TR_LISTED_IN_ML: spec = TR_LISTED_IN_subtree_to_spec(ml); break;
case TR_CORR_ML: spec = TR_CORR_subtree_to_spec(ml); break;
case TR_OF_IN_ML: spec = TR_OF_IN_subtree_to_spec(ml); break;
default: CHILD_UNCONVERTIBLE(VAL_ML);
}
return spec;
}
#line 657 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TR_CORR_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(TR_CORR_ML);
spec = Specifications__Storage__new_TABLE_ENTRY();
Specifications__set_argument(spec, 0, TABLE_COLUMN_MC_to_spec(Parser__SP__MeaningLists__down(ml)));
Specifications__set_argument(spec, 1, TABLE_COLUMN_MC_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml))));
Specifications__set_argument(spec, 2,
Parser__SP__Conversion__VAL_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)))));
Specifications__set_argument(spec, 3,
Parser__SP__Conversion__VAL_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml))))));
return spec;
}
#line 672 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TR_ENTRY_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(TR_ENTRY_ML);
spec = Specifications__Storage__new_TABLE_ENTRY();
Specifications__set_argument(spec, 0, TABLE_COLUMN_MC_to_spec(Parser__SP__MeaningLists__down(ml)));
if ((Code__LocalVariables__are_we_using_table_lookup() == FALSE) &&
(problem_count == 0)) {
Problems__sentence_problem(_P_(C12NoRowSelected),
"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.)");
}
return spec;
}
#line 697 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TR_IN_ROW_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(TR_IN_ROW_ML);
spec = Specifications__Storage__new_TABLE_ENTRY();
Specifications__set_argument(spec, 0, TABLE_COLUMN_MC_to_spec(Parser__SP__MeaningLists__down(ml)));
Specifications__set_argument(spec, 1, Parser__SP__Conversion__VAL_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml))));
Specifications__set_argument(spec, 2, Parser__SP__Conversion__VAL_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)))));
return spec;
}
#line 709 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TR_LISTED_IN_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(TR_LISTED_IN_ML);
spec = Specifications__Storage__new_TABLE_ENTRY();
Specifications__set_argument(spec, 0, TABLE_COLUMN_MC_to_spec(Parser__SP__MeaningLists__down(ml)));
Specifications__set_argument(spec, 1, Parser__SP__Conversion__VAL_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml))));
return spec;
}
#line 720 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TR_OF_IN_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(TR_OF_IN_ML);
spec = Specifications__Storage__new_TABLE_ENTRY();
Specifications__set_argument(spec, 0, TABLE_COLUMN_MC_to_spec(Parser__SP__MeaningLists__down(ml)));
Specifications__set_argument(spec, 1, TABLE_COLUMN_MC_to_spec(Parser__SP__MeaningLists__down(ml)));
Specifications__set_argument(spec, 2, Parser__SP__Conversion__VAL_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml))));
Specifications__set_argument(spec, 3, Parser__SP__Conversion__VAL_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)))));
return spec;
}
#line 733 "inform7/Chapter 12/Meaning List Conversions.w"
specification *TYPE_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(TYPE_ML);
spec = Parser__SP__MeaningLists__get_attached_spec(ml);
if (Specifications__Values__is_generic_CONSTANT(spec)) {
kind *K = Specifications__evaluates_to(spec);
if (Kinds__lt(K, K_object)) {
specification *desc = Specifications__Conditions__new_DESCRIPTION();
Specifications__Conditions__set_described_kind(desc, K);
return desc;
}
}
return spec;
}
#line 750 "inform7/Chapter 12/Meaning List Conversions.w"
specification *VAL_LIST_ENTRY_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(VAL_LIST_ENTRY_ML);
spec = Specifications__Storage__new_LIST_ENTRY(
Parser__SP__Conversion__VAL_subtree_to_spec(Parser__SP__MeaningLists__down(ml)),
Parser__SP__Conversion__VAL_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml))));
return spec;
}
#line 761 "inform7/Chapter 12/Meaning List Conversions.w"
specification *VAL_NOTHING_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(VAL_NOTHING_ML);
spec = Specifications__Values__new_nothing_object_constant();
return spec;
}
#line 770 "inform7/Chapter 12/Meaning List Conversions.w"
specification *VAL_PAIR_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(VAL_PAIR_ML);
specification *X = NP_subtree_to_spec(
Parser__SP__MeaningLists__down(ml));
specification *Y = NP_subtree_to_spec(
Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)));
spec = Specifications__Values__new_pair_combination(X, Y);
return spec;
}
#line 783 "inform7/Chapter 12/Meaning List Conversions.w"
specification *VAL_PROP_OF_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING_SUBTREE(VAL_PROP_OF_ML);
if (Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml))) {
int v1, v2, p1, p2;
specification *pts =
PROPERTY_MC_to_spec(Parser__SP__MeaningLists__down(ml));
specification *vts =
Parser__SP__Conversion__VAL_subtree_to_spec(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)));
Parser__SP__MeaningLists__get_text(Parser__SP__MeaningLists__down(ml), &p1, &p2);
Parser__SP__MeaningLists__get_text(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)), &v1, &v2);
spec = Specifications__Storage__new_PROPERTY_VALUE(pts, vts);
if ((p1 >= 0) && (v1 >= 0)) {
spec->word_ref1 = p1;
if (spec->word_ref1 > v1) spec->word_ref1 = v1;
spec->word_ref2 = p2;
if (spec->word_ref2 < v2) spec->word_ref2 = v2;
}
} else {
spec = PROPERTY_MC_to_spec(Parser__SP__MeaningLists__down(ml));
}
return spec;
}
#line 809 "inform7/Chapter 12/Meaning List Conversions.w"
specification *VALUE_PHRASE_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING(VALUE_PHRASE_ML);
spec = general_phrase_to_spec(ml);
return spec;
}
#line 818 "inform7/Chapter 12/Meaning List Conversions.w"
specification *VAL_RESPONSE_subtree_to_spec(meaning_list *ml) {
NOW_CONVERTING(VAL_RESPONSE_ML);
int c = Parser__SP__MeaningLists__match_score(ml);
ml = Parser__SP__MeaningLists__down(ml);
switch(Parser__SP__MeaningLists__production(ml)) {
case MISCELLANEOUS_MC:
switch(Semantics__Nouns__ExcerptMeanings__get_secondary_code(
Parser__SP__MeaningLists__meaning(ml))) {
case RULE_SMC: spec = RULE_SMC_to_spec(ml); break;
default: CHILD_UNCONVERTIBLE(VAL_RESPONSE_ML);
}
break;
default: CHILD_UNCONVERTIBLE(VAL_RESPONSE_ML);
}
Specifications__set_data(spec, RESPONSE_CODE_SPDATA, c);
Specifications__set_kind_of_value(spec, K_response);
return spec;
}
#line 844 "inform7/Chapter 12/Meaning List Conversions.w"
specification *ACTION_NAME_SMC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(MISCELLANEOUS_MC);
action_name *an = RETRIEVE_POINTER_action_name(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = action_name_to_action_name_spec(an);
return spec;
}
specification *ACTIVITY_MC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(ACTIVITY_MC);
activity *av = RETRIEVE_POINTER_activity(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = Code__Activities__to_specification(av);
return spec;
}
specification *EQUATION_MC_to_spec(meaning_list *ml) {
specification *spec;
int w1, w2, named = TRUE;
equation *eqn = NULL;
if (Parser__SP__MeaningLists__production(ml) == EQUATION_MC) {
eqn = RETRIEVE_POINTER_equation(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
} else {
Parser__SP__MeaningLists__get_text(ml, &w1, &w2);
eqn = Data__Equations__new(w1, w2, TRUE);
named = FALSE;
}
ml = Parser__SP__MeaningLists__right(ml);
if (ml) {
Parser__SP__MeaningLists__get_text(ml, &w1, &w2);
if (named == FALSE) Data__Equations__set_wherewithal(eqn, w1, w2);
else Data__Equations__set_usage_notes(eqn, w1, w2);
}
if (named == FALSE) {
Data__Equations__declare_local_variables(eqn);
Data__Equations__examine(eqn);
}
spec = equation_to_equation_spec(eqn);
return spec;
}
specification *PROPERTY_MC_to_spec(meaning_list *ml) {
RECORD_MLC_BACKTRACE;
if (Parser__SP__MeaningLists__production(ml) == UNPARSED_ML) {
int w1, w2;
specification *spec = Specifications__Unknown__new(-1, -1);
Parser__SP__MeaningLists__get_text(ml, &w1, &w2);
spec->word_ref1 = w1; spec->word_ref2 = w2;
return spec;
}
property *prn = RETRIEVE_POINTER_property(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
return Properties__to_specification(prn);
}
specification *NAMED_CONSTANT_MC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(NAMED_CONSTANT_MC);
instance *I = RETRIEVE_POINTER_instance(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = Specifications__Values__new_named_CONSTANT(I);
return spec;
}
specification *PHRASE_CONSTANT_MC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(PHRASE_CONSTANT_MC);
constant_phrase *cphr = RETRIEVE_POINTER_constant_phrase(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = constant_phrase_to_MAP_spec(cphr);
return spec;
}
specification *RELATION_SMC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(MISCELLANEOUS_MC);
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = binary_predicate_to_RELATION_spec(bp);
return spec;
}
specification *RULE_MC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(RULE_MC);
rule *R = RETRIEVE_POINTER_rule(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = Code__Rules__to_specification(R);
return spec;
}
specification *RULE_SMC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(MISCELLANEOUS_MC);
rule *R = RETRIEVE_POINTER_rule(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = Code__Rules__to_specification(R);
return spec;
}
specification *RULEBOOK_MC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(RULEBOOK_MC);
rulebook *rb = RETRIEVE_POINTER_rulebook(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = Code__Rulebooks__to_specification(rb);
return spec;
}
specification *RULE_OUTCOME_SMC_to_spec(meaning_list *ml, int as_value) {
NOW_CONVERTING_LEAF(MISCELLANEOUS_MC);
named_rulebook_outcome *nro =
RETRIEVE_POINTER_named_rulebook_outcome(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
if (as_value) spec = named_rulebook_outcome_to_rulebook_outcome_spec(nro);
else spec = Specifications__Commands__new_RULEBOOK_OUTCOME_COMMAND(nro);
return spec;
}
specification *TABLE_MC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(TABLE_MC);
table *t = RETRIEVE_POINTER_table(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = table_to_table_spec(t);
return spec;
}
specification *TABLE_COLUMN_MC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(TABLE_COLUMN_MC);
table_column *tc = RETRIEVE_POINTER_table_column(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = Data__Tables__Columns__to_specification(tc);
return spec;
}
specification *USE_OPTION_SMC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(MISCELLANEOUS_MC);
use_option *uo = RETRIEVE_POINTER_use_option(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = use_option_to_use_option_spec(uo);
return spec;
}
specification *VARIABLE_MC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(VARIABLE_MC);
nonlocal_variable *nlv = RETRIEVE_POINTER_nonlocal_variable(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
spec = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(nlv);
return spec;
}
specification *NAMETAG_MC_to_spec(meaning_list *ml) {
NOW_CONVERTING_LEAF(NAMETAG_MC);
nametag *nt = Data__Nametags__disambiguate(ml, MAX_NAMETAG_PRIORITY);
if (Data__Nametags__priority(nt) == INSTANCE_PRIORITY) {
instance *I = RETRIEVE_POINTER_instance(Data__Nametags__tag_holder(nt));
spec = Data__Instances__get_value(I);
} else spec = Specifications__Unknown__new(-1, -1);
return spec;
}
#line 990 "inform7/Chapter 12/Meaning List Conversions.w"
kind *police_te(meaning_list *ml) {
kind *K = NULL;
if (ml != NULL) {
specification *spec = Parser__SP__Conversion__TE_subtree_to_spec(ml);
if (Specifications__is_UNKNOWN(spec)) return NULL;
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
if (Specifications__Conditions__get_described_instance(spec) != NULL)
{
#line 1016 "inform7/Chapter 12/Meaning List Conversions.w"
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C12TypeCantVary));
Problems__issue_problem_segment(
"In %1, '%9' is a contradiction in terms, as this is something that "
"cannot ever vary.");
Problems__issue_problem_end();
return K_object; /* to prevent further errors */
}
#line 997 "inform7/Chapter 12/Meaning List Conversions.w"
;
if ((Specifications__Conditions__number_of_adjectives_applied_to(spec) > 0) ||
(Specifications__Conditions__get_described_kind(spec) == NULL))
{
#line 1027 "inform7/Chapter 12/Meaning List Conversions.w"
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C12TypeUnmaintainable));
Problems__issue_problem_segment(
"In %1, '%9' 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();
return K_object; /* to prevent further errors */
}
#line 1000 "inform7/Chapter 12/Meaning List Conversions.w"
;
K = Specifications__Conditions__get_described_kind(spec);
} else {
if (Specifications__is_actual(spec))
{
#line 1016 "inform7/Chapter 12/Meaning List Conversions.w"
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C12TypeCantVary));
Problems__issue_problem_segment(
"In %1, '%9' is a contradiction in terms, as this is something that "
"cannot ever vary.");
Problems__issue_problem_end();
return K_object; /* to prevent further errors */
}
#line 1004 "inform7/Chapter 12/Meaning List Conversions.w"
;
if (Specifications__get_kind(spec) == NULL)
{
#line 1039 "inform7/Chapter 12/Meaning List Conversions.w"
Problems__handmade_problem(_P_(BelievedImpossible));
Problems__quote_source(1, current_sentence);
Problems__issue_problem_segment(
"In %1, '%9' is not a kind of value which a variable is allowed to "
"have. (See the table at the end of the Kinds index for a list of "
"the kinds allowed.)");
Problems__issue_problem_end();
return K_number; /* to prevent further errors */
}
#line 1006 "inform7/Chapter 12/Meaning List Conversions.w"
;
K = Specifications__get_kind(spec);
}
}
return K;
}
#line 1061 "inform7/Chapter 12/Meaning List Conversions.w"
specification *general_phrase_to_spec(meaning_list *ml) {
int instead_flag = FALSE, group_count = 0, mw1, mw2;
specification *spec;
RECORD_MLC_BACKTRACE;
Parser__SP__MeaningLists__get_text(ml, &mw1, &mw2);
switch(Parser__SP__MeaningLists__production(ml)) {
case PHRASE_ML: spec = Specifications__Commands__new_TO_PHRASE(); break;
case COND_PHRASE_ML: spec = Specifications__Conditions__new_PHRASE_TO_DECIDE_IF(); break;
case VALUE_PHRASE_ML: spec = Specifications__Values__new_PHRASE_TO_DECIDE_VALUE(); break;
default: CHILD_UNCONVERTIBLE(TE_ML);
}
if (mw1 >= 0) { spec->word_ref1 = mw1; spec->word_ref2 = mw2; }
ml = Parser__SP__MeaningLists__down(ml);
if (Parser__SP__MeaningLists__production(ml) == INSTEAD_ML) { instead_flag = TRUE; ml = Parser__SP__MeaningLists__down(ml); }
switch(Parser__SP__MeaningLists__production(ml)) {
case SAY_ML:
{
#line 1120 "inform7/Chapter 12/Meaning List Conversions.w"
for (ml=Parser__SP__MeaningLists__down(ml); ml; group_count++, ml=Parser__SP__MeaningLists__right(ml)) {
specification *this_group = Specifications__Commands__new_TO_PHRASE();
{
#line 1135 "inform7/Chapter 12/Meaning List Conversions.w"
meaning_list *ml2;
for (ml2 = ml; ml2; ml2 = Parser__SP__MeaningLists__sideways(ml2)) {
if (Parser__SP__MeaningLists__production(ml2) == SAY_VERB_ML) {
verb_conjugation *vc =
RETRIEVE_POINTER_verb_conjugation(
Parser__SP__MeaningLists__get_attached_data(ml2));
int neg = Parser__SP__MeaningLists__match_score(ml2);
verb_conjugation *modal = NULL;
meaning_list *modal_annotation = Parser__SP__MeaningLists__down(ml2);
if (modal_annotation)
modal =
RETRIEVE_POINTER_verb_conjugation(
Parser__SP__MeaningLists__get_attached_data(modal_annotation));
invocation *inv = Code__Invocations__new();
Code__Invocations__clear_flag(inv, UNPROVEN_INVFLAG);
Code__Invocations__set_word_range(inv, ml2->word_ref1, ml2->word_ref2);
Code__Invocations__set_verb_conjugation(inv, vc, modal, neg);
Code__Invocations__Lists__add(Specifications__invocation_list(this_group), inv);
} else if (Parser__SP__MeaningLists__production(ml2) == SAY_ADJECTIVE_ML) {
adjectival_phrase *aph =
RETRIEVE_POINTER_adjectival_phrase(
Parser__SP__MeaningLists__get_attached_data(ml2));
invocation *inv = Code__Invocations__new();
Code__Invocations__clear_flag(inv, UNPROVEN_INVFLAG);
Code__Invocations__set_word_range(inv, ml2->word_ref1, ml2->word_ref2);
Code__Invocations__set_adjectival_phrase(inv, aph);
Code__Invocations__Lists__add(Specifications__invocation_list(this_group), inv);
} else {
phrase *ph = RETRIEVE_POINTER_phrase(
Semantics__Nouns__ExcerptMeanings__data(
Parser__SP__MeaningLists__meaning(ml2)));
invocation *inv = Code__Phrases__TypeData__parse_against(ph, ml2);
if ((Code__Phrases__TypeData__is_the_primordial_say(&(ph->type_data)) == FALSE) &&
(Specifications__Values__is_CONSTANT_of_kind(
Code__Invocations__get_token_as_parsed(inv, 0), K_text)))
continue;
Code__Invocations__Lists__add(Specifications__invocation_list(this_group), inv);
}
}
}
#line 1122 "inform7/Chapter 12/Meaning List Conversions.w"
;
{
#line 1178 "inform7/Chapter 12/Meaning List Conversions.w"
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_INVOCATION_LIST(inv, Specifications__invocation_list(this_group))
Code__Invocations__set_group(inv, group_count);
Code__Invocations__Lists__append(Specifications__invocation_list(spec), Specifications__invocation_list(this_group));
}
#line 1123 "inform7/Chapter 12/Meaning List Conversions.w"
;
}
}
#line 1082 "inform7/Chapter 12/Meaning List Conversions.w"
; break;
case END_PHRASE_MC:
{
#line 1188 "inform7/Chapter 12/Meaning List Conversions.w"
spec = Specifications__Commands__new_END_BLOCK(RETRIEVE_POINTER_phrase(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml))));
}
#line 1083 "inform7/Chapter 12/Meaning List Conversions.w"
; break;
default:
{
#line 1102 "inform7/Chapter 12/Meaning List Conversions.w"
for (; ml; ml = Parser__SP__MeaningLists__sideways(ml)) {
phrase *ph;
if (Parser__SP__MeaningLists__meaning(ml) == NULL) internal_error("Blank phrase meaning");
ph = RETRIEVE_POINTER_phrase(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
invocation *inv = Code__Phrases__TypeData__parse_against(ph, ml);
Code__Invocations__Lists__add(Specifications__invocation_list(spec), inv);
}
group_count = 1; /* since just one group was added */
}
#line 1084 "inform7/Chapter 12/Meaning List Conversions.w"
; break;
}
int len = Code__Invocations__Lists__length(Specifications__invocation_list(spec));
if (len >= MAX_INVOCATIONS_PER_PHRASE)
{
#line 1214 "inform7/Chapter 12/Meaning List Conversions.w"
Code__Invocations__Lists__log(Specifications__invocation_list(spec));
Specifications__Unknown__coerce(spec);
spec->word_ref1 = current_sentence->word_ref1; spec->word_ref2 = current_sentence->word_ref2;
Problems__quote_source(1, current_sentence);
Problems__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();
return spec;
}
#line 1089 "inform7/Chapter 12/Meaning List Conversions.w"
;
if (len > 0) {
{
#line 1201 "inform7/Chapter 12/Meaning List Conversions.w"
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_INVOCATION_LIST(inv, Specifications__invocation_list(spec))
if (Code__Invocations__get_group(inv) == group_count-1)
Code__Invocations__set_instead_flag(inv, instead_flag);
}
#line 1091 "inform7/Chapter 12/Meaning List Conversions.w"
;
Code__Invocations__Lists__sort(Specifications__invocation_list(spec));
}
return spec;
}
#line 1236 "inform7/Chapter 12/Meaning List Conversions.w"
specification *qualified_noun_to_spec(meaning_list *adjlist, meaning_list *noun) {
specification *spec = NULL;
if (noun) {
meaning_list *compositor = Parser__SP__MeaningLists__down(noun);
switch (Parser__SP__MeaningLists__production(noun)) {
case NAMETAG_MC:
{
#line 1263 "inform7/Chapter 12/Meaning List Conversions.w"
nametag *nt = Data__Nametags__disambiguate(noun, MAX_NAMETAG_PRIORITY);
if (nt == NULL) {
LOG("At: $m\n", noun);
internal_error("no nametag follows disambiguation");
} else {
if (Data__Nametags__priority(nt) == KIND_PRIORITY) {
kind *k = Kinds__base_construction(
RETRIEVE_POINTER_kind_constructor(Data__Nametags__tag_holder(nt)));
spec = Specifications__Conditions__new_DESCRIPTION();
Specifications__Conditions__set_described_kind(spec, k);
} else if (adjlist) {
instance *I = RETRIEVE_POINTER_instance(Data__Nametags__tag_holder(nt));
spec = Specifications__Conditions__new_DESCRIPTION();
Specifications__Conditions__set_described_instance(spec, I);
} else {
instance *I = RETRIEVE_POINTER_instance(Data__Nametags__tag_holder(nt));
spec = Data__Instances__get_value(I);
}
}
}
#line 1242 "inform7/Chapter 12/Meaning List Conversions.w"
;
break;
case TYPE_ML:
{
#line 1287 "inform7/Chapter 12/Meaning List Conversions.w"
kind *K = Specifications__get_kind(Parser__SP__MeaningLists__get_attached_spec(noun));
spec = Specifications__Conditions__new_DESCRIPTION();
Specifications__Conditions__set_described_kind(spec, K);
}
#line 1245 "inform7/Chapter 12/Meaning List Conversions.w"
;
break;
default: internal_error("Unknown noun production type");
}
if (compositor) Specifications__Conditions__set_composite_flag(spec);
} else spec = Specifications__Conditions__new_DESCRIPTION();
if (adjlist)
{
#line 1294 "inform7/Chapter 12/Meaning List Conversions.w"
meaning_list *ml = adjlist;
int mw1, mw2; Parser__SP__MeaningLists__get_text(ml, &mw1, &mw2);
if (Parser__SP__MeaningLists__production(ml) != AL_ML) internal_error("Non-AL production");
ml = Parser__SP__MeaningLists__down(ml);
if (ml == NULL) internal_error("Empty AL production");
while (ml) {
adjective_list_entry *ale = adj_to_adjective_list_entry(ml);
Specifications__Conditions__add_to_adjective_list(ale, spec);
ml = Parser__SP__MeaningLists__right(ml);
}
}
#line 1251 "inform7/Chapter 12/Meaning List Conversions.w"
;
return spec;
}
#line 1309 "inform7/Chapter 12/Meaning List Conversions.w"
adjective_list_entry *adj_to_adjective_list_entry(meaning_list *ml) {
adjective_list_entry *ale = NULL;
int negate = FALSE;
meaning_list *ml2 = ml;
RECORD_MLC_BACKTRACE;
RetrySwitch:
switch(Parser__SP__MeaningLists__production(ml2)) {
case ADJ_NOT_ML:
ml2 = Parser__SP__MeaningLists__down(ml); negate = TRUE;
goto RetrySwitch;
case ADJECTIVE_MC:
ale = Specifications__Conditions__new_adjective_list_entry(
RETRIEVE_POINTER_adjectival_phrase(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml2))),
(negate)?FALSE:TRUE);
break;
default: internal_error("Unexpected AL production");
}
return ale;
}
#line 1332 "inform7/Chapter 12/Meaning List Conversions.w"
specification *general_sentence_to_spec(meaning_list *ml) {
specification *spec;
meaning_list *subject_noun_phrase = NULL, *verb_phrase = NULL;
verb_usage *vu = NULL; preposition_usage *pu = NULL;
int mw1, mw2; Parser__SP__MeaningLists__get_text(ml, &mw1, &mw2);
RECORD_MLC_BACKTRACE; Problems__s_subtree_error_set_position(ml);
LOGIF(CONDITIONS, "general_sentence_to_spec applied to:\n$m", ml);
{
#line 1368 "inform7/Chapter 12/Meaning List Conversions.w"
if (Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)) == NULL) {
switch(Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml))) {
case DC_ML: {
meaning_list *ml2 = Parser__SP__MeaningLists__down(ml);
Parser__SP__MeaningLists__set_down(ml, Parser__SP__MeaningLists__new(NP_ML));
Parser__SP__MeaningLists__set_down(Parser__SP__MeaningLists__down(ml), Parser__SP__MeaningLists__new(ABSENT_SUBJECT_ML));
Parser__SP__MeaningLists__set_right(Parser__SP__MeaningLists__down(ml), Parser__SP__MeaningLists__new(VP_ML));
verb_phrase = Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml));
Parser__SP__MeaningLists__set_down(verb_phrase, Parser__SP__MeaningLists__new(VERB_ML));
Parser__SP__MeaningLists__set_right(Parser__SP__MeaningLists__down(verb_phrase), ml2);
Parser__SP__MeaningLists__attach_data(Parser__SP__MeaningLists__down(verb_phrase),
STORE_POINTER_verb_usage(regular_to_be));
Parser__SP__MeaningLists__set_production(ml, SV_ML);
Parser__SP__correct_S_subtree_for_adjectives(Parser__SP__MeaningLists__down(ml));
break;
}
default:
Problems__s_subtree_error("only one child with no assumed subject");
}
}
}
#line 1341 "inform7/Chapter 12/Meaning List Conversions.w"
;
{
#line 1393 "inform7/Chapter 12/Meaning List Conversions.w"
subject_noun_phrase = Parser__SP__MeaningLists__down(ml);
verb_phrase = Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml));
if (Parser__SP__MeaningLists__down(verb_phrase) == NULL) Problems__s_subtree_error("VP childless");
if (Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(verb_phrase)) == NULL)
Problems__s_subtree_error("VP only one child");
if (Parser__SP__MeaningLists__production(verb_phrase) != VP_ML)
Problems__s_subtree_error("VP not a VP");
if (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(verb_phrase)) != VERB_ML)
Problems__s_subtree_error("child of VP not a verb");
vu = RETRIEVE_POINTER_verb_usage(Parser__SP__MeaningLists__get_attached_data(Parser__SP__MeaningLists__down(verb_phrase)));
if (vu == NULL) Problems__s_subtree_error("verb null");
if (Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(verb_phrase))) {
if (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(verb_phrase))) != PREP_ML)
Problems__s_subtree_error("child of VERB not a PREP");
pu = RETRIEVE_POINTER_preposition_usage(
Parser__SP__MeaningLists__get_attached_data(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(verb_phrase))));
if (pu == NULL) Problems__s_subtree_error("PREP null");
}
}
#line 1342 "inform7/Chapter 12/Meaning List Conversions.w"
;
switch(Parser__SP__MeaningLists__production(ml)) {
case SN_ML:
spec = Specifications__Conditions__new_DESCRIPTION();
Specifications__set_proposition(spec, Parser__SP__Conversion__S_subtree(ml, NULL));
s_subtree_accumulate_headword(spec, ml);
break;
case SV_ML:
spec = Specifications__Conditions__new_TEST_PROPOSITION(Parser__SP__Conversion__S_subtree(ml, NULL));
break;
default: CHILD_UNCONVERTIBLE(VAL_ML);
}
if (mw1 >= 0) { spec->word_ref1 = mw1; spec->word_ref2 = mw2; }
if (Semantics__VerbUsage__get_tense_used(vu) != IS_TENSE)
{
#line 1420 "inform7/Chapter 12/Meaning List Conversions.w"
if (Parser__SP__MeaningLists__production(ml) == SN_ML) {
Problems__sentence_problem(_P_(C12DescSubordinatePast),
"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.");
} else if (Calculus__Deferrals__detect_locals(Specifications__get_proposition(spec), NULL) > 0) {
Problems__sentence_problem(_P_(C12DescLocalPast),
"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.");
} else Specifications__Conditions__attach_tense(spec, Semantics__VerbUsage__get_tense_used(vu));
}
#line 1358 "inform7/Chapter 12/Meaning List Conversions.w"
;
LOGIF(CONDITIONS, "general_sentence_to_spec result:\n$S", spec);
return spec;
}
#line 1444 "inform7/Chapter 12/Meaning List Conversions.w"
void s_subtree_accumulate_headword(specification *spec,
meaning_list *s_ml) {
instance *subtree_inst;
specification *subtree_spec;
LOGIF(CONDITIONS, "s_subtree_accumulate_headword applied to:\n$m", s_ml);
if (Parser__SP__MeaningLists__production(s_ml) == DC_ML)
subtree_spec = Parser__SP__Conversion__DC_subtree_to_spec(Parser__SP__MeaningLists__down(s_ml), FALSE);
else
subtree_spec = NP_subtree_to_spec(Parser__SP__MeaningLists__down(s_ml));
subtree_inst = Specifications__Values__instance_of_CONSTANT_object_if_any(subtree_spec);
if (subtree_inst) {
Specifications__Conditions__restrict_DESCRIPTION_domain(spec, subtree_inst);
{
#line 1502 "inform7/Chapter 12/Meaning List Conversions.w"
if (Parser__SP__MeaningLists__production(s_ml) == SN_ML) {
verb_usage *vu;
meaning_list *verb_phrase = Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(s_ml));
if (verb_phrase == NULL) Problems__s_subtree_error("no VP");
if (Parser__SP__MeaningLists__down(verb_phrase) == NULL) Problems__s_subtree_error("VP childless");
if (Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(verb_phrase)) == NULL)
Problems__s_subtree_error("VP only one child");
if (Parser__SP__MeaningLists__production(verb_phrase) != VP_ML)
Problems__s_subtree_error("VP not a VP");
if (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(verb_phrase)) != VERB_ML)
Problems__s_subtree_error("child of VP not a verb");
vu = RETRIEVE_POINTER_verb_usage(Parser__SP__MeaningLists__get_attached_data(Parser__SP__MeaningLists__down(verb_phrase)));
if (vu == NULL) Problems__s_subtree_error("verb null");
if ((Semantics__VerbUsage__get_meaning(vu) == R_equality) &&
(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(verb_phrase)) == NULL) &&
(Semantics__VerbUsage__get_tense_used(vu) == IS_TENSE)) {
s_subtree_accumulate_headword(spec, Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(verb_phrase)));
}
}
}
#line 1459 "inform7/Chapter 12/Meaning List Conversions.w"
;
return;
}
if (Specifications__species_is(subtree_spec, DESCRIPTION_SPC)) {
kind *K = Specifications__Conditions__get_described_kind(subtree_spec);
{
#line 1487 "inform7/Chapter 12/Meaning List Conversions.w"
adjective_list_entry *tr_from;
LOOP_THROUGH_ADJECTIVE_LIST(tr_from, subtree_spec) {
adjective_list_entry *tr_new = Specifications__Conditions__copy_adjective_list_entry(tr_from);
Specifications__Conditions__add_to_adjective_list(tr_new, spec);
}
}
#line 1465 "inform7/Chapter 12/Meaning List Conversions.w"
;
if (Specifications__Conditions__get_described_instance(subtree_spec))
Specifications__Conditions__restrict_DESCRIPTION_domain(spec,
Specifications__Conditions__get_described_instance(subtree_spec));
else if ((K) && (Kinds__lt(K, K_object)))
Specifications__Conditions__restrict_DESCRIPTION_to_kind(spec, K);
{
#line 1502 "inform7/Chapter 12/Meaning List Conversions.w"
if (Parser__SP__MeaningLists__production(s_ml) == SN_ML) {
verb_usage *vu;
meaning_list *verb_phrase = Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(s_ml));
if (verb_phrase == NULL) Problems__s_subtree_error("no VP");
if (Parser__SP__MeaningLists__down(verb_phrase) == NULL) Problems__s_subtree_error("VP childless");
if (Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(verb_phrase)) == NULL)
Problems__s_subtree_error("VP only one child");
if (Parser__SP__MeaningLists__production(verb_phrase) != VP_ML)
Problems__s_subtree_error("VP not a VP");
if (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(verb_phrase)) != VERB_ML)
Problems__s_subtree_error("child of VP not a verb");
vu = RETRIEVE_POINTER_verb_usage(Parser__SP__MeaningLists__get_attached_data(Parser__SP__MeaningLists__down(verb_phrase)));
if (vu == NULL) Problems__s_subtree_error("verb null");
if ((Semantics__VerbUsage__get_meaning(vu) == R_equality) &&
(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(verb_phrase)) == NULL) &&
(Semantics__VerbUsage__get_tense_used(vu) == IS_TENSE)) {
s_subtree_accumulate_headword(spec, Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(verb_phrase)));
}
}
}
#line 1471 "inform7/Chapter 12/Meaning List Conversions.w"
;
return;
}
if ((Specifications__species_is(subtree_spec, CONSTANT_SPC)) ||
(Specifications__Storage__get_storage_form(subtree_spec) == LOCAL_VARIABLE_SPC) ||
(Specifications__Storage__get_storage_form(subtree_spec) == NONLOCAL_VARIABLE_SPC))
return;
Specifications__Unknown__coerce(spec);
}
#line 92 "inform7/Chapter 13/Terms.w"
pcalc_term Calculus__Terms__new_variable(int v) {
pcalc_term pt;
{
#line 116 "inform7/Chapter 13/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 93 "inform7/Chapter 13/Terms.w"
;
if ((v < 0) || (v >= 26)) internal_error("bad variable term created");
pt.variable = v;
return pt;
}
pcalc_term Calculus__Terms__new_constant(specification *c) {
pcalc_term pt;
{
#line 116 "inform7/Chapter 13/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 100 "inform7/Chapter 13/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 116 "inform7/Chapter 13/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 106 "inform7/Chapter 13/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 142 "inform7/Chapter 13/Terms.w"
char *pcalc_vars = "xyzabcdefghijklmnopqrstuvw";
#line 149 "inform7/Chapter 13/Terms.w"
specification *Calculus__Terms__constant_underlying(pcalc_term *t) {
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->variable >= 0) return t->variable;
if (t->function) return Calculus__Terms__variable_underlying(&(t->function->fn_of));
return -1;
}
#line 173 "inform7/Chapter 13/Terms.w"
pcalc_term Calculus__Terms__adj_to_noun_conversion(adjective_list_entry *tr) {
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(tr);
instance *I = Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(aph);
if (I) return Calculus__Terms__new_constant(Specifications__Values__new_named_CONSTANT(I));
property *prn = Semantics__Adjectives__Phrases__has_EORP_meaning(aph);
if (prn) return Calculus__Terms__new_constant(Properties__to_specification(prn));
return Calculus__Terms__new_variable(0);
}
#line 185 "inform7/Chapter 13/Terms.w"
adjective_list_entry *Calculus__Terms__noun_to_adj_conversion(pcalc_term pt) {
kind *K;
adjectival_phrase *aph;
specification *spec = pt.constant;
if (Specifications__Values__is_actual_CONSTANT(spec) == FALSE) return NULL;
K = Specifications__get_kind(spec);
if (Kinds__get_coinciding_property(K) == NULL) return NULL;
if (Kinds__is_an_enumeration(K)) {
instance *I = RETRIEVE_FROM_SPEC(spec, instance);
aph = Data__Instances__get_adjectival_phrase(I);
return Specifications__Conditions__new_adjective_list_entry(aph, TRUE);
}
return NULL;
}
#line 206 "inform7/Chapter 13/Terms.w"
void Calculus__Terms__log(pcalc_term *pt) {
if (pt == NULL) {
LOG("<null-term>");
} else if (pt->constant) {
specification *spec = pt->constant;
if (pt->cinder >= 0) { LOG("const_%d", pt->cinder); return; }
if (spec->word_ref1 >= 0) { LOG("'$W'", spec->word_ref1, spec->word_ref2); return; }
if (Specifications__species_is(spec, CONSTANT_SPC)) {
instance *I = Specifications__Values__instance_of_CONSTANT_object_if_any(spec);
if (I) { LOG("$O", I); return; }
}
if (spec->word_ref1 >= 0) { LOG("<$W>", spec->word_ref1, spec->word_ref2); return; }
LOG("$S", spec);
} else if (pt->function) {
binary_predicate *bp = pt->function->bp;
i6_schema *fn = Semantics__BPs__get_term_as_function_of_other(bp, 0);
if (fn == NULL) fn = Semantics__BPs__get_term_as_function_of_other(bp, 1);
if (fn == NULL) internal_error("Function of non-functional predicate");
if (logging_to_I6_text) {
Code__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 84 "inform7/Chapter 13/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 98 "inform7/Chapter 13/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 112 "inform7/Chapter 13/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 144 "inform7/Chapter 13/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->calling_data = parameter;
return prop;
}
#line 156 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_quantifier(pcalc_prop *prop) {
if ((prop) && (prop->element == QUANTIFIER_ATOM)) return TRUE;
return FALSE;
}
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 197 "inform7/Chapter 13/Atomic Propositions.w"
int Calculus__Atoms__is_now_assertable_quantifier(pcalc_prop *prop) {
if (prop->element != QUANTIFIER_ATOM) return FALSE;
return Semantics__Quantifiers__is_now_assertable(RETRIEVE_POINTER_quantifier(prop->predicate));
}
#line 206 "inform7/Chapter 13/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 216 "inform7/Chapter 13/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 226 "inform7/Chapter 13/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 236 "inform7/Chapter 13/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 247 "inform7/Chapter 13/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 257 "inform7/Chapter 13/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 279 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__CALLED_new(int w1, int w2, pcalc_term pt, kind *K) {
pcalc_prop *prop = Calculus__Atoms__new(CALLED_ATOM);
prop->arity = 1;
prop->terms[0] = pt;
prop->calling_data = w1 + ((w2-w1) << 20);
prop->assert_kind = K;
return prop;
}
void Calculus__Atoms__CALLED_get_name(pcalc_prop *prop, int *w1, int *w2) {
*w1 = prop->calling_data & ((1<<20)-1);
*w2 = (prop->calling_data >> 20) + *w1;
}
#line 318 "inform7/Chapter 13/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 352 "inform7/Chapter 13/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 366 "inform7/Chapter 13/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_list_entry(
Specifications__Conditions__new_adjective_list_entry(aph, (negated)?FALSE:TRUE));
return prop;
}
#line 378 "inform7/Chapter 13/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 403 "inform7/Chapter 13/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__prop_x_is_constant(specification *spec) {
return Calculus__Atoms__binary_PREDICATE_new(R_equality,
Calculus__Terms__new_variable(0), Calculus__Terms__new_constant(spec));
}
#line 411 "inform7/Chapter 13/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 420 "inform7/Chapter 13/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 445 "inform7/Chapter 13/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 493 "inform7/Chapter 13/Atomic Propositions.w"
adjective_list_entry *tr = RETRIEVE_POINTER_adjective_list_entry(prop->predicate);
if (Specifications__Conditions__adjective_used_positively(tr) == FALSE) LOG("not-");
Semantics__Adjectives__log(Specifications__Conditions__get_adjective_from_list_entry(tr));
}
#line 450 "inform7/Chapter 13/Atomic Propositions.w"
; break;
case 2:
{
#line 500 "inform7/Chapter 13/Atomic Propositions.w"
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(prop->predicate);
if (bp == NULL) LOG("?bad-bp?"); else LOG(Semantics__BPs__get_log_name(bp));
}
#line 451 "inform7/Chapter 13/Atomic Propositions.w"
; break;
default: LOG("?exotic-predicate-arity=%d?", prop->arity); break;
}
break;
case QUANTIFIER_ATOM: {
quantifier *quant = RETRIEVE_POINTER_quantifier(prop->predicate);
Semantics__Quantifiers__log(quant, prop->calling_data);
LOG(" ");
{
#line 508 "inform7/Chapter 13/Atomic Propositions.w"
int t;
for (t=0; t<prop->arity; t++) {
if (t>0) LOG(", ");
Calculus__Terms__log(&(prop->terms[t]));
}
}
#line 458 "inform7/Chapter 13/Atomic Propositions.w"
;
return;
}
case CALLED_ATOM: {
int w1, w2;
Calculus__Atoms__CALLED_get_name(prop, &w1, &w2);
LOG("called='$W'", w1, w2);
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 508 "inform7/Chapter 13/Atomic Propositions.w"
int t;
for (t=0; t<prop->arity; t++) {
if (t>0) LOG(", ");
Calculus__Terms__log(&(prop->terms[t]));
}
}
#line 486 "inform7/Chapter 13/Atomic Propositions.w"
; LOG(")");
}
}
#line 141 "inform7/Chapter 13/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 13/Propositions.w"
char *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 13/Propositions.w"
void Calculus__Propositions__log(pcalc_prop *prop) {
TRAVERSE_VARIABLE(p);
LOG("[ ");
TRAVERSE_PROPOSITION(p, prop) {
char *bridge = debugging_log_text_between(p_prev, p);
if (bridge[0]) LOG("%s ", bridge);
Calculus__Atoms__log(p);
LOG(" ");
}
LOG("]");
}
#line 234 "inform7/Chapter 13/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 276 "inform7/Chapter 13/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; copied_atom->next = NULL;
if (first) last->next = copied_atom;
else first = copied_atom;
last = copied_atom;
prop = prop->next;
}
return first;
}
#line 294 "inform7/Chapter 13/Propositions.w"
pcalc_prop *Calculus__Propositions__concatenate(pcalc_prop *existing_body, pcalc_prop *tail) {
pcalc_prop *end = existing_body;
if (end == NULL) return tail;
while (end && (end->next)) end = end->next;
end->next = tail;
return existing_body;
}
#line 305 "inform7/Chapter 13/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 316 "inform7/Chapter 13/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 332 "inform7/Chapter 13/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 350 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__length(pcalc_prop *prop) {
int n = 0;
TRAVERSE_VARIABLE(p);
TRAVERSE_PROPOSITION(p, prop) n++;
return n;
}
#line 378 "inform7/Chapter 13/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 404 "inform7/Chapter 13/Propositions.w"
pcalc_prop *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 416 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__contains_binary_predicate(pcalc_prop *prop) {
if (prop_seek_atom(prop, PREDICATE_ATOM, 2)) return TRUE; return FALSE;
}
int Calculus__Propositions__contains_quantifier(pcalc_prop *prop) {
if (prop_seek_atom(prop, QUANTIFIER_ATOM, -1)) return TRUE; return FALSE;
}
pcalc_prop *Calculus__Propositions__composited_kind(pcalc_prop *prop) {
pcalc_prop *k_atom = 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 = 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 (prop_seek_atom(prop, CALLED_ATOM, -1)) return TRUE; return FALSE;
}
#line 447 "inform7/Chapter 13/Propositions.w"
kind *Calculus__Propositions__describes_kind(pcalc_prop *prop) {
pcalc_prop *p = prop;
while ((p = prop_seek_atom(prop, ISAKIND_ATOM, 1)) != NULL) {
if ((Calculus__Terms__variable_underlying(&(p->terms[0])) == 0) &&
(Kinds__eq(p->assert_kind, K_value))) return p->assert_kind;
p = p->next;
}
p = prop;
while ((p = prop_seek_atom(p, KIND_ATOM, 1)) != NULL) {
if (Calculus__Terms__variable_underlying(&(p->terms[0])) == 0) return p->assert_kind;
p = p->next;
}
return NULL;
}
#line 466 "inform7/Chapter 13/Propositions.w"
int Calculus__Propositions__contains_adjective(pcalc_prop *prop) {
if (prop_seek_atom(prop, PREDICATE_ATOM, 1)) return TRUE;
/* while ((prop = prop_seek_atom(prop, PREDICATE_ATOM, 1)) != NULL) {
adjective_list_entry *tr = RETRIEVE_POINTER_adjective_list_entry(prop->predicate);
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(tr);
if (Semantics__Adjectives__Phrases__has_EORP_meaning(aph) == NULL) return TRUE;
return TRUE;
prop = prop->next;
}
*/
return FALSE;
}
#line 483 "inform7/Chapter 13/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 499 "inform7/Chapter 13/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_list_entry *tr = RETRIEVE_POINTER_adjective_list_entry(prop->predicate);
return Calculus__Terms__adj_to_noun_conversion(tr);
}
if (prop->element == KIND_ATOM) {
kind *K = prop->assert_kind;
property *pname = Kinds__get_coinciding_property(K);
if (pname) return Calculus__Terms__new_constant(Properties__to_specification(pname));
}
return pct;
}
#line 527 "inform7/Chapter 13/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 543 "inform7/Chapter 13/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 558 "inform7/Chapter 13/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 568 "inform7/Chapter 13/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 603 "inform7/Chapter 13/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 616 "inform7/Chapter 13/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 78 "inform7/Chapter 13/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("$o invalid because of %c Q for F\n", 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 13/Binding and Substitution.w"
int Calculus__Propositions__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 13/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 13/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 13/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 13/Binding and Substitution.w"
void 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]);
term_map(pt, renumber_map);
}
if (preserving) term_map(preserving, renumber_map);
}
void 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 13/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++;
}
vars_map(prop, renumber_map, preserving);
}
#line 231 "inform7/Chapter 13/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 13/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 13/Binding and Substitution.w"
;
renumber_map[j] = next_unused++;
} else renumber_map[j] = -1;
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 13/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 13/Binding and Substitution.w"
int substitute_v_in_term(pcalc_term *pt, int v, pcalc_term *t) {
if (pt->variable == v) { *pt = *t; return TRUE; }
if (pt->function) return substitute_v_in_term(&(pt->function->fn_of), v, t);
return FALSE;
}
void Calculus__Propositions__substitute_nothing_in_term(pcalc_term *pt, pcalc_term *t) {
if ((pt->constant) && (Specifications__Values__is_nothing_object_constant(pt->constant))) { *pt = *t; return; }
if (pt->function) Calculus__Propositions__substitute_nothing_in_term(&(pt->function->fn_of), t);
}
void Calculus__Propositions__substitute_term_in_term(pcalc_term *pt, pcalc_term *t) {
if (pt->constant) { *pt = *t; return; }
if (pt->function) Calculus__Propositions__substitute_term_in_term(&(pt->function->fn_of), t);
}
#line 331 "inform7/Chapter 13/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__Propositions__is_well_formed(prop) == FALSE)
DISALLOW("substituting into malformed prop");
{
#line 371 "inform7/Chapter 13/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 13/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 (substitute_v_in_term(&(p->terms[i]), v, &t))
*changed = TRUE;
}
if (Calculus__Propositions__is_well_formed(prop) == FALSE)
internal_error("substitution made malformed prop");
return prop;
}
#line 400 "inform7/Chapter 13/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 13/Binding and Substitution.w"
pcalc_prop *Calculus__Propositions__substitute_var_0_in(pcalc_prop *prop, specification *spec) {
int bogus;
return Calculus__Variables__substitute_term(prop, 0, Calculus__Terms__new_constant(spec), FALSE, NULL, &bogus);
}
#line 421 "inform7/Chapter 13/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_list_entry *tr = RETRIEVE_POINTER_adjective_list_entry(p->predicate);
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(tr);
adjective_meaning *am = Semantics__Adjectives__first_meaning(aph);
kind *K = Semantics__Adjectives__Meanings__get_domain(am);
if (K) return K;
}
}
return NULL;
}
#line 49 "inform7/Chapter 13/Propositional Form.w"
pcalc_prop *Calculus__Propositions__from_spec(specification *spec, int quantify) {
pcalc_prop *prop = NULL;
if (spec == NULL) return NULL; /* the null description is universally true */
if (Specifications__get_proposition(spec)) return Specifications__get_proposition(spec); /* a propositional form is already made */
int c1, c2;
Specifications__Conditions__get_calling(spec, &c1, &c2);
if (c1 >= 0) prop = Calculus__Propositions__concatenate(prop,
Calculus__Atoms__CALLED_new(c1, c2, Calculus__Terms__new_variable(0),
Specifications__Conditions__get_described_kind(spec)));
{
#line 81 "inform7/Chapter 13/Propositional Form.w"
instance *I = Specifications__Values__get_named_constant_if_any(spec);
if (I) {
property *pname = Kinds__get_coinciding_property(Data__Instances__kind(I));
if (pname) {
prop = Calculus__Propositions__concatenate(prop,
Calculus__Atoms__unary_PREDICATE_from_aph(Data__Instances__get_adjectival_phrase(I), FALSE));
{
#line 164 "inform7/Chapter 13/Propositional Form.w"
Calculus__Propositions__type_check(prop, Calculus__Propositions__tc_no_problem_reporting());
return prop;
}
#line 87 "inform7/Chapter 13/Propositional Form.w"
;
}
}
}
#line 61 "inform7/Chapter 13/Propositional Form.w"
;
{
#line 94 "inform7/Chapter 13/Propositional Form.w"
if (Specifications__Values__is_CONSTANT_construction(spec, CON_property)) {
property *prn = Properties__from_specification(spec);
if (Properties__is_either_or(prn)) {
prop = Calculus__Propositions__concatenate(prop, Calculus__Atoms__unary_PREDICATE_from_aph(
Properties__EitherOr__get_aph(prn), FALSE));
{
#line 164 "inform7/Chapter 13/Propositional Form.w"
Calculus__Propositions__type_check(prop, Calculus__Propositions__tc_no_problem_reporting());
return prop;
}
#line 99 "inform7/Chapter 13/Propositional Form.w"
;
}
}
}
#line 62 "inform7/Chapter 13/Propositional Form.w"
;
{
#line 106 "inform7/Chapter 13/Propositional Form.w"
if ((Specifications__species_is(spec, DESCRIPTION_SPC) == FALSE) &&
(Specifications__Values__is_CONSTANT_construction(spec, CON_description) == FALSE)) {
prop = Calculus__Propositions__concatenate(prop, Calculus__Atoms__prop_x_is_constant(Specifications__copy(spec)));
{
#line 164 "inform7/Chapter 13/Propositional Form.w"
Calculus__Propositions__type_check(prop, Calculus__Propositions__tc_no_problem_reporting());
return prop;
}
#line 109 "inform7/Chapter 13/Propositional Form.w"
;
}
}
#line 63 "inform7/Chapter 13/Propositional Form.w"
;
{
#line 119 "inform7/Chapter 13/Propositional Form.w"
pcalc_prop *head = NULL;
if (Specifications__Conditions__get_described_kind(spec)) {
if (Specifications__Conditions__get_composite_flag(spec)) {
head = Calculus__Atoms__KIND_new_composited(
Specifications__Conditions__get_described_kind(spec), Calculus__Terms__new_variable(0));
} else {
head = Calculus__Atoms__KIND_new(
Specifications__Conditions__get_described_kind(spec), Calculus__Terms__new_variable(0));
}
} else if (Specifications__Conditions__get_described_instance(spec)) {
specification *the_object = Data__Instances__get_value(Specifications__Conditions__get_described_instance(spec));
head = Calculus__Atoms__prop_x_is_constant(the_object);
}
if (head) prop = Calculus__Propositions__concatenate(prop, head);
}
#line 65 "inform7/Chapter 13/Propositional Form.w"
;
{
#line 138 "inform7/Chapter 13/Propositional Form.w"
adjective_list_entry *ale;
LOOP_THROUGH_ADJECTIVE_LIST(ale, spec) {
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(ale);
int negated = FALSE;
if (Specifications__Conditions__adjective_used_positively(ale) == FALSE) negated = TRUE;
prop = Calculus__Propositions__concatenate(prop, Calculus__Atoms__unary_PREDICATE_from_aph(aph, negated));
}
}
#line 66 "inform7/Chapter 13/Propositional Form.w"
;
if (quantify)
{
#line 149 "inform7/Chapter 13/Propositional Form.w"
if (Specifications__Conditions__get_quantifier(spec)) {
if (Specifications__Conditions__get_quantifier(spec) != exists_quantifier)
prop = Calculus__Propositions__concatenate(Calculus__Atoms__new(DOMAIN_OPEN_ATOM), prop);
prop = Calculus__Propositions__concatenate(
Calculus__Atoms__QUANTIFIER_new(Specifications__Conditions__get_quantifier(spec), 0,
Specifications__Conditions__get_quantification_parameter(spec)), prop);
if (Specifications__Conditions__get_quantifier(spec) != exists_quantifier)
prop = Calculus__Propositions__concatenate(prop, Calculus__Atoms__new(DOMAIN_CLOSE_ATOM));
}
}
#line 68 "inform7/Chapter 13/Propositional Form.w"
;
{
#line 164 "inform7/Chapter 13/Propositional Form.w"
Calculus__Propositions__type_check(prop, Calculus__Propositions__tc_no_problem_reporting());
return prop;
}
#line 70 "inform7/Chapter 13/Propositional Form.w"
;
}
#line 18 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__to_make_a_kind(kind *K) {
return Calculus__Atoms__ISAKIND_new(Calculus__Terms__new_variable(0), K);
}
pcalc_prop *Calculus__Propositions__to_make_a_var(void) {
return Calculus__Atoms__ISAVAR_new(Calculus__Terms__new_variable(0));
}
pcalc_prop *Calculus__Propositions__to_make_a_const(void) {
return Calculus__Atoms__ISACONST_new(Calculus__Terms__new_variable(0));
}
pcalc_prop *Calculus__Propositions__to_create_something(kind *K, int w1, int w2) {
pcalc_prop *prop = Calculus__Atoms__QUANTIFIER_new(exists_quantifier, 0, 0);
if ((K) && (Kinds__eq(K, K_object) == FALSE))
prop = Calculus__Propositions__concatenate(prop,
Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0)));
if (w1 >= 0)
prop = Calculus__Propositions__concatenate(prop,
Calculus__Atoms__CALLED_new(w1, w2, Calculus__Terms__new_variable(0), K));
return prop;
}
#line 44 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop *prop_to_set_kind(instance *I, kind *k) {
return Calculus__Atoms__KIND_new(k, Calculus__Terms__new_variable(0));
}
void Calculus__Propositions__assert_kind_of_object(instance *I, kind *k) {
Calculus__Propositions__assert_true_about(prop_to_set_kind(I, k),
Data__Instances__as_subject(I), prevailing_mood);
}
void Calculus__Propositions__assert_kind_of_subject(inference_subject *inst, inference_subject *new,
pcalc_prop *subject_to) {
kind *K = World__Subjects__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_true_about(prop, inst, prevailing_mood);
}
#line 64 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__to_set_simple_relation(binary_predicate *bp, instance *I) {
specification *spec;
if (I) spec = Data__Instances__get_value(I);
else spec = Specifications__Values__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__to_set_relation(binary_predicate *bp,
inference_subject *infs0, specification *spec0, inference_subject *infs1, specification *spec1) {
pcalc_term pt0, pt1;
if (infs0) pt0 = Calculus__Terms__new_constant(World__Subjects__as_constant(infs0));
else pt0 = Calculus__Terms__new_constant(spec0);
if (infs1) pt1 = Calculus__Terms__new_constant(World__Subjects__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 13/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__to_provide_property(property *prn) {
return Calculus__Atoms__binary_PREDICATE_new(R_provision,
Calculus__Terms__new_variable(0), Calculus__Terms__new_constant(Properties__to_specification(prn)));
}
pcalc_prop *Calculus__Propositions__to_set_property(property *prn, specification *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 13/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__to_put_everywhere(void) {
return Calculus__Atoms__EVERYWHERE_new(Calculus__Terms__new_variable(0));
}
pcalc_prop *Calculus__Propositions__to_put_nowhere(void) {
return Calculus__Atoms__NOWHERE_new(Calculus__Terms__new_variable(0));
}
pcalc_prop *Calculus__Propositions__to_put_here(void) {
return Calculus__Atoms__HERE_new(Calculus__Terms__new_variable(0));
}
#line 120 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__from_property_subtree(property *prn, parse_node *py) {
return Calculus__Propositions__to_set_property(prn, Parser__Assertions__property_value_from_property_subtree(prn, py));
}
#line 130 "inform7/Chapter 13/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__from_property_list(parse_node *p, kind *K) {
pcalc_prop *prop = NULL;
if (p) {
switch(Parser__Nodes__type(p)) {
case AND_NT:
for (p = p->down; p; p = p->next)
prop = Calculus__Propositions__conjoin(prop, Calculus__Propositions__from_property_list(p, NULL));
break;
case PROPERTY_LIST_NT:
{
#line 158 "inform7/Chapter 13/Tree Conversions.w"
property *prn = NULL;
int pw1 = -1, pw2 = 0, vw1 = -1, vw2 = 0;
{
#line 214 "inform7/Chapter 13/Tree Conversions.w"
if ((p->word_ref1 < 0) || (p->word_ref2 < p->word_ref1)) {
Problems__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(p->word_ref1, p->word_ref2);
if (name_length < 0) {
name_length = 1;
if (parse_nt_against_word_range(literal_NTM, p->word_ref2, p->word_ref2, NULL, NULL))
name_length = p->word_ref2 - p->word_ref1;
}
pw1 = p->word_ref1; pw2 = p->word_ref1+name_length-1;
vw1 = pw2+1; vw2 = p->word_ref2;
}
#line 160 "inform7/Chapter 13/Tree Conversions.w"
;
if ((pw1 >= 0) && (pw1 <= pw2) && (parse_nt_against_word_range(property_name_NTM, pw1, pw2, NULL, NULL))) prn = most_recent_result_p;
if (prn == NULL)
{
#line 234 "inform7/Chapter 13/Tree Conversions.w"
LOG("Failed property list: pname = <$W>; pval = <$W>\n", pw1, pw2, vw1, vw2);
Problems__assertion_problem(_P_(C13BadPropertyList),
"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 163 "inform7/Chapter 13/Tree Conversions.w"
;
if ((vw1 >= 0) && (vw1 <= vw2)) { /* a value is supplied... */
if (Properties__is_either_or(prn)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, p->word_ref1, p->word_ref2);
Problems__quote_property(3, prn);
Problems__quote_words(4, vw1, vw2);
Problems__handmade_problem(_P_(C13WithEitherOrValue));
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;
}
parse_nt_against_word_range(nounphrase_as_object_NTM, vw1, vw2, NULL, NULL);
parse_node *pn = most_recent_result_p;
Parser__Nodes__refine(pn, FORBID_CREATION);
prop = Calculus__Propositions__conjoin(prop, Calculus__Propositions__from_property_subtree(prn, pn));
} else { /* no value is supplied... */
if (Properties__is_either_or(prn) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, p->word_ref1, p->word_ref2);
Problems__quote_property(3, prn);
Problems__quote_kind(4, Properties__Valued__kind(prn));
Problems__handmade_problem(_P_(C13WithValuelessValue));
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__from_property_subtree(prn, NULL));
}
}
#line 140 "inform7/Chapter 13/Tree Conversions.w"
;
break;
case ADJECTIVE_NT:
{
#line 256 "inform7/Chapter 13/Tree Conversions.w"
int negate_me = FALSE;
if (Parser__Nodes__int_annotation(p, negated_boolean_ANNOT)) negate_me = TRUE;
if (Parser__Nodes__get_aph(p) == NULL)
internal_error("Bogus adjective at Calculus__Propositions__from_property_list");
if (Parser__Nodes__get_creation_proposition(p))
prop = Calculus__Propositions__conjoin(prop, Parser__Nodes__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(Parser__Nodes__get_aph(p), FALSE));
if (negate_me) prop = Calculus__Propositions__conjoin(prop, Calculus__Atoms__new(NEGATION_CLOSE_ATOM));
}
#line 143 "inform7/Chapter 13/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 13/Sentence Conversions.w"
int conv_log_depth = 0; /* recursion depth: used only to clarify the debugging log */
pcalc_prop *Parser__SP__Conversion__S_subtree(meaning_list *ml, pcalc_term *subject_of_sentence) {
int w1, w2, SV_not_SN = FALSE;
meaning_list *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;
int verb_phrase_negated = FALSE;
pcalc_prop *sentence_prop = NULL;
{
#line 76 "inform7/Chapter 13/Sentence Conversions.w"
if (ml == NULL) internal_error("Parser__SP__Conversion__S_subtree on null S-subtree");
switch(Parser__SP__MeaningLists__production(ml)) {
case SN_ML: SV_not_SN = FALSE; break;
case SV_ML: SV_not_SN = TRUE; break;
default: internal_error("Parser__SP__Conversion__S_subtree on non-S-subtree");
}
Problems__s_subtree_error_set_position(ml);
Parser__SP__MeaningLists__get_text(ml, &w1, &w2);
if (conv_log_depth == 0) LOGIF(PREDICATE_CALCULUS, "-----------\n");
conv_log_depth++;
LOGIF(PREDICATE_CALCULUS, "[%d] Starting Parser__SP__Conversion__S_subtree on: <$W>\n", conv_log_depth, w1, w2);
}
#line 42 "inform7/Chapter 13/Sentence Conversions.w"
;
if (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml)) == THERE_ML) {
{
#line 112 "inform7/Chapter 13/Sentence Conversions.w"
if (SV_not_SN == FALSE) internal_error("THERE subtree misplaced");
specification *spec = Parser__SP__Conversion__DC_subtree_to_spec(
Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(ml)))))), FALSE);
sentence_prop = Calculus__Propositions__from_spec(spec, TRUE);
sentence_prop = Calculus__Variables__bind_existential(sentence_prop, NULL);
}
#line 45 "inform7/Chapter 13/Sentence Conversions.w"
;
} else {
{
#line 129 "inform7/Chapter 13/Sentence Conversions.w"
meaning_list *verb_phrase_subtree;
verb_usage *vu; preposition_usage *pu = NULL;
subject_phrase_subtree = Parser__SP__MeaningLists__down(ml);
if (subject_phrase_subtree == NULL) Problems__s_subtree_error("SP subtree null");
verb_phrase_subtree = Parser__SP__MeaningLists__right(subject_phrase_subtree);
if (verb_phrase_subtree == NULL) Problems__s_subtree_error("VP subtree null");
if (Parser__SP__MeaningLists__down(verb_phrase_subtree) == NULL) Problems__s_subtree_error("VP subtree broken");
object_phrase_subtree = Parser__SP__MeaningLists__right(Parser__SP__MeaningLists__down(verb_phrase_subtree));
if (object_phrase_subtree == NULL) Problems__s_subtree_error("OP subtree null");
vu = RETRIEVE_POINTER_verb_usage(Parser__SP__MeaningLists__get_attached_data(Parser__SP__MeaningLists__down(verb_phrase_subtree)));
if (vu == NULL) Problems__s_subtree_error("verb null");
if ((SV_not_SN == FALSE) && (Semantics__VerbUsage__get_tense_used(vu) != IS_TENSE))
{
#line 162 "inform7/Chapter 13/Sentence Conversions.w"
Problems__sentence_problem(_P_(C13PastSubordinate),
"subordinate clauses have to be in the present tense",
"so 'the Black Door was open' is fine, but not 'if the Black Door is "
"something locked which had been open'. Only the main verb can be in "
"the past tense.");
}
#line 143 "inform7/Chapter 13/Sentence Conversions.w"
;
if (Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(verb_phrase_subtree))) {
if (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(verb_phrase_subtree))) != PREP_ML)
Problems__s_subtree_error("child of VERB not a PREP");
pu = RETRIEVE_POINTER_preposition_usage(
Parser__SP__MeaningLists__get_attached_data(Parser__SP__MeaningLists__down(Parser__SP__MeaningLists__down(verb_phrase_subtree))));
if (pu == NULL) Problems__s_subtree_error("PREP null");
}
if (pu) verb_phrase_relation = Semantics__PrepositionUsage__get_meaning(pu);
else verb_phrase_relation = Semantics__VerbUsage__get_meaning(vu);
verb_phrase_negated = (Semantics__VerbUsage__is_used_negatively(vu))?TRUE:FALSE;
if ((pu) && (Semantics__PrepositionUsage__implicitly_negates(pu)))
verb_phrase_negated = (verb_phrase_negated)?FALSE:TRUE;
}
#line 47 "inform7/Chapter 13/Sentence Conversions.w"
;
{
#line 226 "inform7/Chapter 13/Sentence Conversions.w"
kind *subject_K = Semantics__BPs__term_kind(verb_phrase_relation, 0);
if (Kinds__lt(subject_K, K_object)) subject_K = NULL;
subject_phrase_prop =
NP_subtree_to_proposition(&subject_phrase_term, subject_phrase_subtree,
subject_K);
kind *object_K = Semantics__BPs__term_kind(verb_phrase_relation, 1);
if (Kinds__lt(object_K, K_object)) object_K = NULL;
object_phrase_prop =
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 48 "inform7/Chapter 13/Sentence Conversions.w"
;
{
#line 266 "inform7/Chapter 13/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 49 "inform7/Chapter 13/Sentence Conversions.w"
;
{
#line 359 "inform7/Chapter 13/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 392 "inform7/Chapter 13/Sentence Conversions.w"
pcalc_prop *k_atom = Calculus__Propositions__composited_kind(object_phrase_prop);
if ((k_atom) && (Kinds__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 = Semantics__BPs__get_reversal(room_containment_predicate);
LOGIF(PREDICATE_CALCULUS, "[%d] Decompositing object: $D\n",
conv_log_depth, object_phrase_prop);
}
}
#line 363 "inform7/Chapter 13/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 50 "inform7/Chapter 13/Sentence Conversions.w"
;
}
{
#line 445 "inform7/Chapter 13/Sentence Conversions.w"
if (Calculus__Propositions__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 53 "inform7/Chapter 13/Sentence Conversions.w"
;
{
#line 92 "inform7/Chapter 13/Sentence Conversions.w"
LOGIF(PREDICATE_CALCULUS, "[%d] Parser__SP__Conversion__S_subtree: $W --> $D\n",
conv_log_depth, w1, w2, sentence_prop);
conv_log_depth--;
}
#line 54 "inform7/Chapter 13/Sentence Conversions.w"
;
if (subject_of_sentence) *subject_of_sentence = subject_phrase_term;
return sentence_prop;
}
#line 485 "inform7/Chapter 13/Sentence Conversions.w"
pcalc_prop *NP_subtree_to_proposition(pcalc_term *subject_of_NP, meaning_list *ml,
kind *K) {
pcalc_prop *NP_prop = NULL; int w1, w2;
{
#line 512 "inform7/Chapter 13/Sentence Conversions.w"
Parser__SP__MeaningLists__get_text(ml, &w1, &w2);
conv_log_depth++;
LOGIF(PREDICATE_CALCULUS, "[%d] Starting NP_subtree_to_proposition on: <$W>\n",
conv_log_depth, w1, w2);
}
#line 489 "inform7/Chapter 13/Sentence Conversions.w"
;
{
#line 540 "inform7/Chapter 13/Sentence Conversions.w"
if (ml == NULL) internal_error("Null ML");
if (Parser__SP__MeaningLists__production(ml) == NP_ML) ml = Parser__SP__MeaningLists__down(ml);
if ((Parser__SP__MeaningLists__production(ml) == VAL_ML) && (Parser__SP__MeaningLists__down(ml)) &&
(Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml)) == DC_ML)) ml = Parser__SP__MeaningLists__down(ml);
if ((Parser__SP__MeaningLists__production(ml) == DC_ML) && (Parser__SP__MeaningLists__down(ml)) &&
(Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml)) == SN_ML)) ml = Parser__SP__MeaningLists__down(ml);
}
#line 490 "inform7/Chapter 13/Sentence Conversions.w"
;
switch(Parser__SP__MeaningLists__production(ml)) {
case SN_ML: NP_prop = Parser__SP__Conversion__S_subtree(ml, subject_of_NP); break;
case VAL_ML:
{
#line 562 "inform7/Chapter 13/Sentence Conversions.w"
specification *spec = Parser__SP__Conversion__VAL_subtree_to_spec(ml);
*subject_of_NP = Calculus__Terms__new_constant(spec);
if (Specifications__Values__is_CONSTANT_construction(spec, CON_property)) {
property *prn = Properties__from_specification(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 494 "inform7/Chapter 13/Sentence Conversions.w"
; break;
case DC_ML:
{
#line 585 "inform7/Chapter 13/Sentence Conversions.w"
specification *spec = Parser__SP__Conversion__DC_subtree_to_spec(ml, FALSE);
NP_prop = Calculus__Propositions__from_spec(spec, TRUE);
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)) &&
(parse_nt_against_word_range(k_formal_kind_variable_singular_NTM, w1, w2, NULL, NULL))) {
Calculus__Atoms__set_unarticled(NP_prop, TRUE);
}
if (NP_prop) *subject_of_NP = Calculus__Propositions__get_first_cited_term(NP_prop);
}
#line 495 "inform7/Chapter 13/Sentence Conversions.w"
; break;
case ABSENT_SUBJECT_ML:
{
#line 615 "inform7/Chapter 13/Sentence Conversions.w"
*subject_of_NP = Calculus__Terms__new_constant(Specifications__Values__new_self_object_constant());
}
#line 496 "inform7/Chapter 13/Sentence Conversions.w"
; break;
default: LOG("Under NP subtree:\n$m", ml); internal_error("Malformed NP subtree");
}
{
#line 655 "inform7/Chapter 13/Sentence Conversions.w"
if (((Parser__SP__MeaningLists__production(ml) == VAL_ML) && (Parser__SP__MeaningLists__down(ml)) &&
(Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml)) == PROPERTY_MC) &&
(Parser__SP__MeaningLists__match_score(Parser__SP__MeaningLists__down(ml)))) || (K)) {
pcalc_term pct = Calculus__Propositions__convert_adj_to_noun(NP_prop);
if (pct.constant) { *subject_of_NP = pct; NP_prop = NULL; }
}
}
#line 500 "inform7/Chapter 13/Sentence Conversions.w"
;
{
#line 673 "inform7/Chapter 13/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, w1, w2, subject_of_NP, NP_prop);
}
}
#line 501 "inform7/Chapter 13/Sentence Conversions.w"
;
{
#line 695 "inform7/Chapter 13/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 502 "inform7/Chapter 13/Sentence Conversions.w"
;
{
#line 520 "inform7/Chapter 13/Sentence Conversions.w"
if (Calculus__Propositions__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] NP_subtree_to_proposition: $W --> t = $0, phi = $D\n",
conv_log_depth, w1, w2, subject_of_NP, NP_prop);
conv_log_depth--;
}
#line 504 "inform7/Chapter 13/Sentence Conversions.w"
;
return NP_prop;
}
#line 48 "inform7/Chapter 13/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 (Specifications__Values__is_nothing_object_constant(Calculus__Terms__constant_underlying(&(pl->terms[i])))) {
{
#line 105 "inform7/Chapter 13/Simplifications.w"
int nv = Calculus__Variables__find_unused(prop);
pcalc_term new_var = Calculus__Terms__new_variable(nv);
Calculus__Propositions__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 (Semantics__BPs__term_kind(bp, i))
prop = Calculus__Propositions__insert_atom(prop, position,
Calculus__Atoms__KIND_new(Semantics__BPs__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 13/Simplifications.w"
;
PROPOSITION_EDITED(pl, prop);
break;
}
}
}
return prop;
}
#line 163 "inform7/Chapter 13/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++) {
specification *spec = Calculus__Terms__constant_underlying(&(pl->terms[j]));
if ((spec) && (Specifications__Storage__get_storage_form(spec) == TABLE_ENTRY_SPC) &&
(Specifications__get_argc(spec) == 2)) {
specification *col = Specifications__get_argument(spec, 0);
specification *tab = Specifications__get_argument(spec, 1);
table_column *tc = Data__Tables__Columns__from_specification(col);
kind *K = Data__Tables__Columns__get_kind(tc);
if (Kinds__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(Data__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(Data__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__Propositions__substitute_term_in_term(&(pl->terms[j]), &nv_term);
Code__LocalVariables__add_table_lookup();
PROPOSITION_EDITED(pl, prop);
}
}
}
return prop;
}
#line 216 "inform7/Chapter 13/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 = prop_ungroup_and_negate_determiner(prop, pl_prev, TRUE);
PROPOSITION_EDITED(pl, prop);
}
}
}
return prop;
}
#line 261 "inform7/Chapter 13/Simplifications.w"
pcalc_prop *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 = Semantics__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, "prop_ungroup_and_negate_determiner: $D\n", prop);
} else internal_error("not a negate-group-determiner");
return prop;
}
#line 303 "inform7/Chapter 13/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 = 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 13/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 = Semantics__BPs__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 13/Simplifications.w"
pcalc_prop *Calculus__Simplifications__redundant_kinds(pcalc_prop *prop, int *changed) {
int c1 = FALSE, c2 = FALSE;
prop = simp_redundant_kinds_dash(prop, prop, 1, &c1);
prop = simp_redundant_kinds_dash(prop, prop, 1, &c2);
if ((c1) || (c2)) *changed = TRUE; else *changed = FALSE;
return prop;
}
#line 403 "inform7/Chapter 13/Simplifications.w"
pcalc_prop *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 13/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 = 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 13/Simplifications.w"
;
{
#line 466 "inform7/Chapter 13/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 13/Simplifications.w"
;
{
#line 533 "inform7/Chapter 13/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 13/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__le(early_kind, later_kind))) {
prop = Calculus__Propositions__delete_atom(prop, gpl_prev);
PROPOSITION_EDITED_REPEATING_CURRENT(gpl, prop);
}
}
}
}
#line 550 "inform7/Chapter 13/Simplifications.w"
;
{
#line 590 "inform7/Chapter 13/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) {
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* that is, delete the current $K(v)$ */
prop = Calculus__Propositions__insert_atom(prop, best_place,
Calculus__Atoms__KIND_new(early_kind, Calculus__Terms__new_variable(v))); /* insert a new one */
PROPOSITION_EDITED_REPEATING_CURRENT(pl, prop);
}
}
#line 551 "inform7/Chapter 13/Simplifications.w"
;
}
}
}
if (blevel == 0) break;
}
}
#line 409 "inform7/Chapter 13/Simplifications.w"
;
{
#line 632 "inform7/Chapter 13/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;
specification *spec = pl->terms[0].constant;
if (Specifications__family_is(spec, VALUE_FMY)) {
kind *K = Specifications__Values__kind_when_VALUE_is_evaluated(spec);
if ((K) && (Kinds__lt(early_kind, K_object) == FALSE) &&
(Kinds__le(early_kind, K))) {
prop = Calculus__Propositions__delete_atom(prop, pl_prev);
PROPOSITION_EDITED_REPEATING_CURRENT(pl, prop);
}
}
}
}
}
}
#line 410 "inform7/Chapter 13/Simplifications.w"
;
return prop;
}
#line 671 "inform7/Chapter 13/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) && (Semantics__BPs__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(Semantics__BPs__get_reversal(bp));
PROPOSITION_EDITED(pl, prop);
}
}
return prop;
}
#line 711 "inform7/Chapter 13/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++) {
instance *the_region =
Specifications__object_exactly_described_if_any(pl->terms[j].constant);
instance *the_item =
Specifications__object_exactly_described_if_any(pl->terms[1-j].constant);
if ((the_region) && (Data__Instances__of_kind(the_region, K_region)) &&
(!((the_item) && (Data__Instances__of_kind(the_item, K_backdrop))))) {
pl->predicate = STORE_POINTER_binary_predicate(R_regional_containment);
PROPOSITION_EDITED(pl, prop);
}
}
}
}
return prop;
}
#line 763 "inform7/Chapter 13/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 ((Semantics__BPs__get_term_as_function_of_other(bp, j)) &&
(Semantics__BPs__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 795 "inform7/Chapter 13/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 846 "inform7/Chapter 13/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 803 "inform7/Chapter 13/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 893 "inform7/Chapter 13/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 814 "inform7/Chapter 13/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 927 "inform7/Chapter 13/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__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__eq(K, Semantics__BPs__term_kind(bp, 1)))) {
specification *new_nothing =
Specifications__Storage__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 974 "inform7/Chapter 13/Simplifications.w"
pcalc_prop *Calculus__Simplifications__convert_gerunds(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 (Specifications__species_is(pl->terms[i].constant, TEST_ACTION_SPC))
Plugins__Actions__coerce_TEST_ACTION_to_DESCRIPTION_OF_ACTION(pl->terms[i].constant);
}
}
return prop;
}
#line 1016 "inform7/Chapter 13/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)) {
specification *spec = pl->terms[i].function->fn_of.constant;
if (Specifications__Values__is_actual_CONSTANT_construction(spec, CON_property))
{
#line 1043 "inform7/Chapter 13/Simplifications.w"
property *prn = Properties__from_specification(spec);
specification *po_spec =
Specifications__Storage__new_PROPERTY_VALUE(spec, pl->terms[1-i].constant);
po_spec->word_ref1 = prn->word_ref1; po_spec->word_ref2 = prn->word_ref2;
int no_substitutions_made;
prop = 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 1030 "inform7/Chapter 13/Simplifications.w"
;
}
}
}
return prop;
}
#line 1061 "inform7/Chapter 13/Simplifications.w"
pcalc_prop *prop_substitute_prop_cons(pcalc_prop *prop, property *prn,
specification *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 (Specifications__Values__is_actual_CONSTANT_construction(pt->constant, CON_property)) {
property *tprn;
tprn = Properties__from_specification(pt->constant);
if (tprn == prn) {
pt->constant = po_spec;
c++;
}
}
}
*count = c;
return prop;
}
#line 1108 "inform7/Chapter 13/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__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__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__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 53 "inform7/Chapter 13/Type Check Propositions.w"
tc_problem_kit Calculus__Propositions__tc_no_problem_reporting(void) {
tc_problem_kit tck;
tck.issue_error = FALSE; tck.ew1 = -1; tck.ew2 = -1; tck.intention = "be silent checking";
tck.log_to_I6_text = FALSE; tck.flag_problem = FALSE; return tck;
}
tc_problem_kit Calculus__Propositions__tc_problem_reporting(int w1, int w2, char *intent) {
tc_problem_kit tck = Calculus__Propositions__tc_no_problem_reporting();
tck.issue_error = TRUE; tck.ew1 = w1; tck.ew2 = w2; tck.intention = intent;
return tck;
}
#line 69 "inform7/Chapter 13/Type Check Propositions.w"
tc_problem_kit Calculus__Propositions__tc_problem_logging(void) {
tc_problem_kit tck = Calculus__Propositions__tc_no_problem_reporting();
tck.intention = "be internal testing"; tck.log_to_I6_text = TRUE; return tck;
}
#line 84 "inform7/Chapter 13/Type Check Propositions.w"
int Calculus__Propositions__type_check(pcalc_prop *prop, tc_problem_kit tck_s) {
TRAVERSE_VARIABLE(pl);
variable_type_assignment vta;
tc_problem_kit *tck = &tck_s;
int j;
if (prop == NULL) return ALWAYS_MATCH;
if (Calculus__Propositions__is_well_formed(prop) == FALSE)
internal_error("type-checking malformed proposition");
{
#line 143 "inform7/Chapter 13/Type Check Propositions.w"
TRAVERSE_PROPOSITION(pl, prop) {
int j;
for (j=0; j<pl->arity; j++) {
specification *spec = Calculus__Terms__constant_underlying(&(pl->terms[j]));
if (spec) {
if ((Specifications__is_UNKNOWN(spec)) ||
((Specifications__is_generic(spec) == FALSE) &&
(Specifications__Matching__check_without_expectations(spec) == NEVER_MATCH)))
{
#line 237 "inform7/Chapter 13/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_words(2, spec->word_ref1, spec->word_ref2);
Problems__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: $S\n", spec);
}
return NEVER_MATCH;
}
#line 151 "inform7/Chapter 13/Type Check Propositions.w"
;
}
}
}
}
#line 94 "inform7/Chapter 13/Type Check Propositions.w"
;
for (j=0; j<26; j++) vta.assigned_kinds[j] = NULL;
{
#line 169 "inform7/Chapter 13/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__le(new_kind, K_object)) new_kind = K_object;
kind *old_kind = vta.assigned_kinds[v];
if (old_kind) {
if (Kinds__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);
issue_kind_typecheck_error(old_kind, new_kind, tck, pl);
return NEVER_MATCH;
}
if (Kinds__definite(new_kind) == FALSE) new_kind = old_kind;
}
vta.assigned_kinds[v] = new_kind;
}
}
}
#line 97 "inform7/Chapter 13/Type Check Propositions.w"
;
{
#line 194 "inform7/Chapter 13/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__handmade_problem(_P_(C13BareKindVariable));
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 98 "inform7/Chapter 13/Type Check Propositions.w"
;
{
#line 228 "inform7/Chapter 13/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 99 "inform7/Chapter 13/Type Check Propositions.w"
;
TRAVERSE_PROPOSITION(pl, prop) {
for (j=0; j<pl->arity; j++) kind_of_term(&(pl->terms[j]), &vta, tck);
if (tck->flag_problem) return NEVER_MATCH;
if (pl->element == KIND_ATOM)
{
#line 265 "inform7/Chapter 13/Type Check Propositions.w"
kind *need_to_find = pl->assert_kind;
if (Kinds__le(need_to_find, K_object)) need_to_find = K_object;
kind *actually_find = kind_of_term(&(pl->terms[0]), &vta, tck);
if (Kinds__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);
issue_kind_typecheck_error(actually_find, need_to_find, tck, pl);
return NEVER_MATCH;
}
}
#line 105 "inform7/Chapter 13/Type Check Propositions.w"
;
if ((pl->element == PREDICATE_ATOM) && (pl->arity == 2))
{
#line 294 "inform7/Chapter 13/Type Check Propositions.w"
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(pl->predicate);
if (Semantics__BPs__is_the_wrong_way_round(bp)) internal_error("BP wrong way round");
if (type_check_binary_predicate(pl, &vta, tck) == NEVER_MATCH) {
if (bp == R_equality) {
adjective_list_entry *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_list_entry(alt);
if (type_check_unary_predicate(&test_unary, &vta, tck) == NEVER_MATCH)
{
#line 314 "inform7/Chapter 13/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 13/Type Check Propositions.w"
;
pl->arity = 1;
pl->predicate = STORE_POINTER_adjective_list_entry(alt);
} else
{
#line 314 "inform7/Chapter 13/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 13/Type Check Propositions.w"
;
} else
{
#line 314 "inform7/Chapter 13/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 13/Type Check Propositions.w"
;
}
}
#line 107 "inform7/Chapter 13/Type Check Propositions.w"
;
if ((pl->element == PREDICATE_ATOM) && (pl->arity == 1))
{
#line 278 "inform7/Chapter 13/Type Check Propositions.w"
if (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 109 "inform7/Chapter 13/Type Check Propositions.w"
;
if (pl->element == EVERYWHERE_ATOM)
{
#line 327 "inform7/Chapter 13/Type Check Propositions.w"
kind *actually_find = kind_of_term(&(pl->terms[0]), &vta, tck);
if (Kinds__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__tcp_problem(_P_(C13EverywhereMisapplied), 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 111 "inform7/Chapter 13/Type Check Propositions.w"
;
if (pl->element == NOWHERE_ATOM)
{
#line 344 "inform7/Chapter 13/Type Check Propositions.w"
kind *actually_find = kind_of_term(&(pl->terms[0]), &vta, tck);
if (Kinds__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__tcp_problem(_P_(C13NowhereMisapplied), 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 113 "inform7/Chapter 13/Type Check Propositions.w"
;
if (pl->element == ISAKIND_ATOM)
{
#line 320 "inform7/Chapter 13/Type Check Propositions.w"
kind *actually_find = kind_of_term(&(pl->terms[0]), &vta, tck);
if (Kinds__compatible(actually_find, K_object) == NEVER_MATCH)
internal_error("ISAKIND atom misapplied");
}
#line 115 "inform7/Chapter 13/Type Check Propositions.w"
;
if (pl->element == HERE_ATOM)
{
#line 361 "inform7/Chapter 13/Type Check Propositions.w"
kind *actually_find = kind_of_term(&(pl->terms[0]), &vta, tck);
if (Kinds__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__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 117 "inform7/Chapter 13/Type Check Propositions.w"
;
}
if (tck->log_to_I6_text)
{
#line 378 "inform7/Chapter 13/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 120 "inform7/Chapter 13/Type Check Propositions.w"
;
return ALWAYS_MATCH;
}
#line 395 "inform7/Chapter 13/Type Check Propositions.w"
kind *kind_of_term(pcalc_term *pt, variable_type_assignment *vta,
tc_problem_kit *tck) {
kind *K = kind_of_term_inner(pt, vta, tck);
pt->term_checked_as_kind = K;
if (K == NULL) tck->flag_problem = TRUE;
return K;
}
#line 410 "inform7/Chapter 13/Type Check Propositions.w"
kind *kind_of_term_inner(pcalc_term *pt, variable_type_assignment *vta,
tc_problem_kit *tck) {
if (pt->constant) return Specifications__evaluates_to(pt->constant);
if (pt->variable >= 0) return vta->assigned_kinds[pt->variable];
if (pt->function) {
binary_predicate *bp = pt->function->bp;
kind *kind_found = kind_of_term(&(pt->function->fn_of), vta, tck);
kind *kind_from = approximate_argument_kind(bp, pt->function->from_term);
kind *kind_to = approximate_argument_kind(bp, 1 - pt->function->from_term);
if ((kind_from) && (Kinds__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__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 13/Type Check Propositions.w"
kind *approximate_argument_kind(binary_predicate *bp, int i) {
kind *K = Semantics__BPs__term_kind(bp, i);
if (K == NULL) return K_object;
return Kinds__weaken(K);
}
#line 453 "inform7/Chapter 13/Type Check Propositions.w"
int type_check_unary_predicate(pcalc_prop *pl, variable_type_assignment *vta,
tc_problem_kit *tck) {
adjective_list_entry *tr = RETRIEVE_POINTER_adjective_list_entry(pl->predicate);
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(tr);
kind *K = kind_of_term(&(pl->terms[0]), vta, tck);
if ((aph) && (Semantics__Adjectives__Phrases__applicable_to(aph, K) == FALSE)) {
int w1, w2;
Semantics__Adjectives__Meanings__get_text(aph, &w1, &w2, FALSE);
if (tck->log_to_I6_text)
LOG("Adjective '$W' undefined on $u\n", w1, w2, K);
Problems__quote_words(4, w1, w2);
Problems__quote_kind(5, K);
Problems__tcp_problem(_P_(C13AdjectiveMisapplied), 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 483 "inform7/Chapter 13/Type Check Propositions.w"
int 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 534 "inform7/Chapter 13/Type Check Propositions.w"
int i;
for (i=0; i<2; i++) {
kind *K = Kinds__weaken(Semantics__BPs__term_kind(bp, i));
if (K == NULL) K = K_object;
kinds_required[i] = K;
kinds_of_terms[i] = kind_of_term(&(pl->terms[i]), vta, tck);
}
}
#line 488 "inform7/Chapter 13/Type Check Propositions.w"
;
int result = Semantics__BPs__typecheck(bp, kinds_of_terms, kinds_required, tck);
if (result == NEVER_MATCH_SAYING_WHY_NOT) {
kind *kinds_dereferencing_properties[2];
kinds_dereferencing_properties[0] = Kinds__dereference_properties(kinds_of_terms[0]);
kinds_dereferencing_properties[1] = Kinds__dereference_properties(kinds_of_terms[1]);
int r2 = Semantics__BPs__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__issue_bp_typecheck_error(pl->terms[0].function->bp,
kind_of_term(&(pl->terms[0].function->fn_of), vta, tck),
kinds_of_terms[1], tck);
else if (pl->terms[1].function)
Calculus__Propositions__issue_bp_typecheck_error(pl->terms[1].function->bp,
kinds_of_terms[0],
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__tcp_problem(_P_(C13ComparisonFailed), 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 546 "inform7/Chapter 13/Type Check Propositions.w"
int i;
for (i=0; i<2; i++)
if (kinds_required[i])
if (Kinds__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__issue_bp_typecheck_error(bp,
kinds_of_terms[0], kinds_of_terms[1], tck);
return NEVER_MATCH;
}
}
#line 524 "inform7/Chapter 13/Type Check Propositions.w"
;
return ALWAYS_MATCH;
}
#line 561 "inform7/Chapter 13/Type Check Propositions.w"
void Calculus__Propositions__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__tcp_problem(_P_(C13TypeCheckBP2), tck,
"that would mean applying %6 to kinds of value which do not "
"fit - %4 and %5 - so this must be incorrect.");
}
void 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__tcp_problem(_P_(C13TypeCheckBP2a), tck,
"that doesn't work because you use %6 with %4 instead of %5.");
} else {
Problems__tcp_problem(_P_(C13TypeCheckKind), tck,
"%4 cannot be %5, so this must be incorrect.");
}
}
#line 20 "inform7/Chapter 14/The Equality Relation.w"
void Calculus__Relations__Equality__create_initial_stock(void) {
R_equality = Semantics__BPs__make_equality();
Semantics__BPs__set_index_details(R_equality, "value", "value");
Semantics__Nouns__ExcerptMeanings__register_assemblage(MISCELLANEOUS_MC, RELATION_SMC,
Text__Languages__merge(relation_name_formal_NTM, 0,
Text__Languages__wording(relation_names_NTM, EQUALITY_RELATION_NAME)),
STORE_POINTER_binary_predicate(R_equality));
}
#line 33 "inform7/Chapter 14/The Equality Relation.w"
void Calculus__Relations__Equality__create_second_stock(void) {
}
#line 41 "inform7/Chapter 14/The Equality Relation.w"
int Calculus__Relations__Equality__typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
if (Config__Plugins__Call__typecheck_equality(kinds_of_terms[0], kinds_of_terms[1]))
return ALWAYS_MATCH;
if ((Kinds__le(kinds_of_terms[0], K_object)) &&
(Kinds__name_can_coincide_with_property(kinds_of_terms[1])))
{
#line 67 "inform7/Chapter 14/The Equality Relation.w"
property *prn = Kinds__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__tcp_problem(_P_(C14NonPropertyCompared), 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 48 "inform7/Chapter 14/The Equality Relation.w"
else if ((Kinds__eq(kinds_of_terms[1], K_understanding)) &&
(Kinds__eq(kinds_of_terms[0], K_snippet)))
return ALWAYS_MATCH;
else if ((Kinds__eq(kinds_of_terms[0], K_understanding)) &&
(Kinds__eq(kinds_of_terms[1], K_snippet)))
return ALWAYS_MATCH;
else if ((Kinds__eq(kinds_of_terms[1], K_text)) &&
(Kinds__eq(kinds_of_terms[0], K_response)))
return ALWAYS_MATCH;
else
{
#line 88 "inform7/Chapter 14/The Equality Relation.w"
if (both_terms_of_same_construction(kinds_of_terms[0], kinds_of_terms[1], CON_rule))
return ALWAYS_MATCH;
if (both_terms_of_same_construction(kinds_of_terms[0], kinds_of_terms[1], CON_rulebook))
return ALWAYS_MATCH;
if (both_terms_of_same_construction(kinds_of_terms[0], kinds_of_terms[1], CON_activity))
return ALWAYS_MATCH;
if ((Kinds__compatible(kinds_of_terms[0], kinds_of_terms[1]) == NEVER_MATCH) &&
(Kinds__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 59 "inform7/Chapter 14/The Equality Relation.w"
;
return ALWAYS_MATCH;
}
#line 104 "inform7/Chapter 14/The Equality Relation.w"
int 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 115 "inform7/Chapter 14/The Equality Relation.w"
int Calculus__Relations__Equality__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
if (Specifications__Storage__is_actual_NONLOCAL_VARIABLE(spec0)) {
nonlocal_variable *q = RETRIEVE_FROM_SPEC(spec0, nonlocal_variable);
int allowed = TRUE;
if ((prevailing_mood != UNKNOWN_CE) && (prevailing_mood != LIKELY_CE))
allowed = FALSE;
if ((Data__NonlocalVariables__is_constant(q)) && (prevailing_mood == CERTAIN_CE))
allowed = TRUE;
if (allowed == FALSE)
Problems__sentence_problem(_P_(C14CantQualifyVariableValues),
"a variable can only be given its value straightforwardly or "
"qualified by 'probably'",
"not with 'always', 'seldom' or 'never'.");
else World__Inferences__draw_property(
Data__NonlocalVariables__get_knowledge(q), P_variable_initial_value, spec1);
return TRUE;
}
return FALSE;
}
#line 169 "inform7/Chapter 14/The Equality Relation.w"
int Calculus__Relations__Equality__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__le(st[0], K_object)) &&
(Kinds__name_can_coincide_with_property(st[1])) && (Kinds__get_coinciding_property(st[1])))
{
#line 228 "inform7/Chapter 14/The Equality Relation.w"
property *prn = Kinds__get_coinciding_property(st[1]);
switch (task) {
case TEST_ATOM_TASK:
Code__Schemas__modify(asch->schema, "*1.%s == *2", Properties__get_translation(prn));
return TRUE;
case NOW_ATOM_FALSE_TASK:
break;
case NOW_ATOM_TRUE_TASK:
Code__Schemas__modify(asch->schema, "*1.%s = *2", Properties__get_translation(prn));
return TRUE;
}
return FALSE;
}
#line 176 "inform7/Chapter 14/The Equality Relation.w"
;
if ((Kinds__eq(st[0], K_response)) && (Kinds__eq(st[1], K_text)))
{
#line 244 "inform7/Chapter 14/The Equality Relation.w"
switch (task) {
case TEST_ATOM_TASK:
Problems__sentence_problem(_P_(C14ResponseComparisonUnsafe),
"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:
Code__Schemas__modify(asch->schema, "BlkValueCopy(ResponseTexts-->((*1)-1), *^2)");
return TRUE;
}
return FALSE;
}
#line 179 "inform7/Chapter 14/The Equality Relation.w"
;
switch (task) {
case TEST_ATOM_TASK:
if ((st[0]) && (st[1]))
Code__Schemas__modify(asch->schema, "%s",
Kinds__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]);
internal_error("null kind in equality test");
}
return TRUE;
case NOW_ATOM_FALSE_TASK:
break;
case NOW_ATOM_TRUE_TASK: {
int storage_class = Specifications__Storage__get_storage_form(asch->pt0.constant);
if ((storage_class == UNKNOWN) &&
(Kinds__get_construct(st[0]) == CON_property))
storage_class = PROPERTY_VALUE_SPC;
if (Config__Plugins__Call__forbid_setting(asch->pt1.term_checked_as_kind)) {
asch->schema = NULL;
return TRUE;
}
{
#line 277 "inform7/Chapter 14/The Equality Relation.w"
if (Kinds__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__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__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 202 "inform7/Chapter 14/The Equality Relation.w"
;
if (storage_class == UNKNOWN) {
{
#line 299 "inform7/Chapter 14/The Equality Relation.w"
if (Specifications__Values__get_named_constant_if_any(asch->pt0.constant))
Problems__sentence_problem(_P_(C14CantChangeNamedConstant),
"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.");
else
Problems__sentence_problem(_P_(C14CantEquateValues),
"equality is not something I can change",
"so either those are already the same or are different, and I "
"can't alter matters.");
}
#line 204 "inform7/Chapter 14/The Equality Relation.w"
asch->schema = NULL;
} else {
{
#line 262 "inform7/Chapter 14/The Equality Relation.w"
nonlocal_variable *nlv =
Specifications__Storage__get_nonlocal_variable_if_any(asch->pt0.constant);
if ((nlv) && (Data__NonlocalVariables__must_be_constant(nlv))) {
asch->schema = NULL;
return TRUE;
}
char *exotica = Data__NonlocalVariables__get_write_schema(nlv);
if (exotica) {
Code__Schemas__modify(asch->schema, "%s", exotica);
return TRUE;
}
}
#line 207 "inform7/Chapter 14/The Equality Relation.w"
;
Code__Schemas__modify(asch->schema, "%s",
Kinds__interpret_store(storage_class, st[0], st[1], 0));
{
#line 317 "inform7/Chapter 14/The Equality Relation.w"
if ((Kinds__compatible(st[1], st[0]) == SOMETIMES_MATCH) &&
(Kinds__lt(st[0], K_object))) {
TEMPORARY_STREAM;
STREAM_WRITE(TEMP,
"; if (~~(*1 ofclass %s)) RunTimeProblem(RTP_WRONGASSIGNEDKIND, *1, \"*?\", \"",
Kinds__I6_classname(st[0]));
Kinds__Textual__write(TEMP, st[0]);
STREAM_WRITE(TEMP, "\");");
Code__Schemas__append(asch->schema, "%s", STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
}
#line 210 "inform7/Chapter 14/The Equality Relation.w"
;
}
return TRUE;
}
}
return FALSE;
}
#line 332 "inform7/Chapter 14/The Equality Relation.w"
int Calculus__Relations__Equality__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 32 "inform7/Chapter 14/Quasinumeric Relations.w"
void Calculus__Relations__Quasinumeric__create_initial_stock(void) {
bp_term_details number_term = Semantics__BPs__Terms__new(Kinds__as_subject(K_number));
R_numerically_greater_than =
Semantics__BPs__make_pair(QUASINUMERIC_KBP,
number_term, number_term,
"greater-than", NULL, NULL, NULL, Code__Schemas__new("*1 > *2"),
Text__Languages__wording(relation_names_NTM, GT_RELATION_NAME));
R_numerically_less_than =
Semantics__BPs__make_pair(QUASINUMERIC_KBP,
number_term, number_term,
"less-than", NULL, NULL, NULL, Code__Schemas__new("*1 < *2"),
Text__Languages__wording(relation_names_NTM, LT_RELATION_NAME));
R_numerically_greater_than_or_equal_to =
Semantics__BPs__make_pair(QUASINUMERIC_KBP,
number_term, number_term,
"at-least", NULL, NULL, NULL, Code__Schemas__new("*1 >= *2"),
Text__Languages__wording(relation_names_NTM, GE_RELATION_NAME));
R_numerically_less_than_or_equal_to =
Semantics__BPs__make_pair(QUASINUMERIC_KBP,
number_term, number_term,
"at-most", NULL, NULL, NULL, Code__Schemas__new("*1 <= *2"),
Text__Languages__wording(relation_names_NTM, LE_RELATION_NAME));
Semantics__BPs__set_index_details(R_numerically_greater_than,
"arithmetic value", "arithmetic value");
Semantics__BPs__set_index_details(R_numerically_less_than,
"arithmetic value", "arithmetic value");
Semantics__BPs__set_index_details(R_numerically_greater_than_or_equal_to,
"arithmetic value", "arithmetic value");
Semantics__BPs__set_index_details(R_numerically_less_than_or_equal_to,
"arithmetic value", "arithmetic value");
}
#line 68 "inform7/Chapter 14/Quasinumeric Relations.w"
void Calculus__Relations__Quasinumeric__create_second_stock(void) {
}
#line 74 "inform7/Chapter 14/Quasinumeric Relations.w"
int Calculus__Relations__Quasinumeric__typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
if ((Kinds__compatible(kinds_of_terms[0], kinds_of_terms[1]) == NEVER_MATCH) &&
(Kinds__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__tcp_problem(_P_(C14InequalityFailed), 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 14/Quasinumeric Relations.w"
int Calculus__Relations__Quasinumeric__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
return FALSE;
}
#line 106 "inform7/Chapter 14/Quasinumeric Relations.w"
int Calculus__Relations__Quasinumeric__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 = Kinds__get_comparison_routine(st[0]);
if ((cr[0] == 0) || (strcmp(cr, "signed") == 0)) return FALSE;
if (bp == R_numerically_greater_than)
Code__Schemas__modify(asch->schema, "*_1(*1, *2) > 0");
if (bp == R_numerically_less_than)
Code__Schemas__modify(asch->schema, "*_1(*1, *2) < 0");
if (bp == R_numerically_greater_than_or_equal_to)
Code__Schemas__modify(asch->schema, "*_1(*1, *2) >= 0");
if (bp == R_numerically_less_than_or_equal_to)
Code__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 135 "inform7/Chapter 14/Quasinumeric Relations.w"
int Calculus__Relations__Quasinumeric__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 88 "inform7/Chapter 14/Assert Propositions.w"
void Calculus__Propositions__assert_true(pcalc_prop *prop, int certitude) {
prop_true_in_world_model_inner(prop, NULL, certitude);
}
void Calculus__Propositions__assert_true_about(pcalc_prop *prop, inference_subject *infs,
int certitude) {
prop_true_in_world_model_inner(prop, infs, certitude);
}
#line 103 "inform7/Chapter 14/Assert Propositions.w"
inference_subject **current_interpretation_as_infs = NULL; /* must point to a 26-element array */
specification **current_interpretation_as_spec = NULL; /* must point to a 26-element array */
#line 109 "inform7/Chapter 14/Assert Propositions.w"
parse_node *last_couldnt_assert_at = NULL;
#line 117 "inform7/Chapter 14/Assert Propositions.w"
void prop_true_in_world_model_inner(pcalc_prop *prop, inference_subject *subject,
int certainty) {
inference_subject **saved_interpretation_as_infs = current_interpretation_as_infs;
specification **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]; specification *ciats[26];
{
#line 142 "inform7/Chapter 14/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 14/Assert Propositions.w"
;
ptim_recursion_depth++;
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 14/Assert Propositions.w"
void prop_true_in_model(pcalc_prop *prop) {
if (prop == NULL) return;
{
#line 202 "inform7/Chapter 14/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 = $S", pcalc_vars[i], current_interpretation_as_spec[i]);
}
}
LOGIF(ASSERTIONS, " $D\n", prop);
}
#line 168 "inform7/Chapter 14/Assert Propositions.w"
;
if (Calculus__Propositions__contains_nonexistence_quantifier(prop))
{
#line 228 "inform7/Chapter 14/Assert Propositions.w"
Problems__sentence_problem(_P_(C14CantAssertQuantifier),
"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 14/Assert Propositions.w"
;
{
#line 242 "inform7/Chapter 14/Assert Propositions.w"
int w1 = -1, w2 = -1;
if (current_sentence) { w1 = current_sentence->word_ref1; w2 = current_sentence->word_ref2; }
if (Calculus__Propositions__type_check(prop,
Calculus__Propositions__tc_problem_reporting(w1, w2, "be asserting something"))
!= ALWAYS_MATCH)
return;
}
#line 171 "inform7/Chapter 14/Assert Propositions.w"
;
{
#line 261 "inform7/Chapter 14/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 14/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 14/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");
int name1 = -1, name2 = -1;
int is_a_var = FALSE, is_a_const = FALSE, is_a_kind = FALSE;
kind *K = NULL;
{
#line 301 "inform7/Chapter 14/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: Calculus__Atoms__CALLED_get_name(lookahead, &name1, &name2); 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 14/Assert Propositions.w"
;
{
#line 316 "inform7/Chapter 14/Assert Propositions.w"
if (is_a_kind) {
K = Kinds__new_base(name1, name2, K);
current_interpretation_as_infs[v] = Kinds__as_subject(K);
current_interpretation_as_spec[v] = Specifications__Values__new_generic_CONSTANT(K);
} else if ((is_a_var) || (is_a_const)) {
if (K == NULL) K = K_object;
nonlocal_variable *q = Data__NonlocalVariables__new_global(name1, name2, K);
current_interpretation_as_infs[v] = NULL;
current_interpretation_as_spec[v] = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(q);
if (is_a_const) Data__NonlocalVariables__make_constant(q, FALSE);
} else {
instance *nc = Data__Instances__new(name1, name2, K);
current_interpretation_as_infs[v] = Data__Instances__as_subject(nc);
if ((K == NULL) || (Kinds__le(K, K_object)))
current_interpretation_as_spec[v] = Data__Instances__get_value(nc);
else
current_interpretation_as_spec[v] = Specifications__Values__new_named_CONSTANT(nc);
}
}
#line 293 "inform7/Chapter 14/Assert Propositions.w"
;
{
#line 339 "inform7/Chapter 14/Assert Propositions.w"
if (current_interpretation_as_spec[v]) {
LOGIF(ASSERTIONS, ":: %c <-- $S\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 14/Assert Propositions.w"
;
}
#line 180 "inform7/Chapter 14/Assert Propositions.w"
; break;
case KIND_ATOM:
{
#line 355 "inform7/Chapter 14/Assert Propositions.w"
if (now_negated) {
Problems__sentence_problem(_P_(C14CantAssertNonKind),
"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 = subject_of_term(pl->terms[0]);
instance *ox = World__Subjects__as_instance(subj);
if (ox) Data__Instances__set_kind(ox, pl->assert_kind);
else {
kind *K = World__Subjects__as_kind(subj);
if (K) Kinds__make_subkind(K, pl->assert_kind);
}
}
#line 181 "inform7/Chapter 14/Assert Propositions.w"
; break;
case PREDICATE_ATOM:
switch (pl->arity) {
case 1:
{
#line 438 "inform7/Chapter 14/Assert Propositions.w"
adjective_list_entry *tr = RETRIEVE_POINTER_adjective_list_entry(pl->predicate);
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(tr);
int parity = (now_negated)?FALSE:TRUE, found;
if (Specifications__Conditions__adjective_used_positively(tr) == FALSE) parity = (parity)?FALSE:TRUE;
inference_subject *ox = subject_of_term(pl->terms[0]);
specification *ots = spec_of_term(pl->terms[0]);
kind *domain_of_definition = World__Subjects__domain(ox);
if (domain_of_definition == NULL) {
instance *inst = World__Subjects__as_instance(ox);
if (inst) domain_of_definition = Data__Instances__kind(inst);
}
inference_subject *try = ox;
while ((domain_of_definition == NULL) && (try)) {
domain_of_definition = World__Subjects__domain(try);
try = World__Subjects__narrowest_broader_subject(try);
}
if (domain_of_definition == NULL)
domain_of_definition = Specifications__get_kind(ots);
if (ox) found = Semantics__Adjectives__Phrases__assert(aph, domain_of_definition, ox, NULL, parity);
else found = Semantics__Adjectives__Phrases__assert(aph, domain_of_definition, NULL, ots, parity);
if (found == FALSE) {
if (last_couldnt_assert_at != current_sentence) {
int w1, w2;
Semantics__Adjectives__Meanings__get_text(aph, &w1, &w2, FALSE);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C14CantAssertAdjective));
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 14/Assert Propositions.w"
; break;
case 2:
{
#line 508 "inform7/Chapter 14/Assert Propositions.w"
if (now_negated) {
Problems__sentence_problem(_P_(C14CantAssertNegatedRelations),
"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 564 "inform7/Chapter 14/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__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 518 "inform7/Chapter 14/Assert Propositions.w"
;
specification *spec0 = spec_of_term(pt0), *spec1 = spec_of_term(pt1);
inference_subject *subj0 = subject_of_term(pt0), *subj1 = subject_of_term(pt1);
if ((subj0) && (spec0 == NULL)) spec0 = World__Subjects__as_constant(subj0);
if ((subj1) && (spec1 == NULL)) spec1 = World__Subjects__as_constant(subj1);
if (bp != R_regional_containment) {
kind *K0 = Semantics__BPs__term_kind(bp, 0);
kind *K1 = Semantics__BPs__term_kind(bp, 1);
if (Kinds__lt(K0, K_object)) cautiously_set_kind(subj0, K0);
if (Kinds__lt(K1, K_object)) cautiously_set_kind(subj1, K1);
}
if (Semantics__BPs__assert(bp, subj0, spec0, subj1, spec1) == FALSE)
{
#line 538 "inform7/Chapter 14/Assert Propositions.w"
LOG("$2 on ($j, $S; $j, $S)\n", bp, subj0, spec0, subj1, spec1);
if ((Specifications__Values__is_nothing_object_constant(spec0)) ||
(Specifications__Values__is_nothing_object_constant(spec1)))
Problems__sentence_problem(_P_(C14RelationFailedOnNothing),
"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__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 533 "inform7/Chapter 14/Assert Propositions.w"
;
}
#line 185 "inform7/Chapter 14/Assert Propositions.w"
; break;
}
break;
case HERE_ATOM:
{
#line 413 "inform7/Chapter 14/Assert Propositions.w"
inference_subject *subj = subject_of_term(pl->terms[0]);
instance *ox = World__Subjects__as_instance(subj);
if (now_negated) {
Problems__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__sentence_problem(_P_(C14NonInstanceHere),
"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;
}
Plugins__Spatial__infer_presence_here(ox);
}
#line 188 "inform7/Chapter 14/Assert Propositions.w"
; break;
case EVERYWHERE_ATOM:
{
#line 378 "inform7/Chapter 14/Assert Propositions.w"
inference_subject *subj = subject_of_term(pl->terms[0]);
instance *ox = World__Subjects__as_instance(subj);
if (now_negated) {
Problems__sentence_problem(_P_(C14CantAssertNegatedEverywhere),
"that seems to say that something isn't everywhere",
"which is too vague. You must say where it is.");
return;
}
Plugins__Backdrops__infer_presence_everywhere(ox);
}
#line 189 "inform7/Chapter 14/Assert Propositions.w"
; break;
case NOWHERE_ATOM:
{
#line 391 "inform7/Chapter 14/Assert Propositions.w"
inference_subject *subj = subject_of_term(pl->terms[0]);
instance *ox = World__Subjects__as_instance(subj);
if (now_negated) {
Problems__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__sentence_problem(_P_(BelievedImpossible),
"that seems to say that something generic is 'nowhere'",
"which suggests it could some day have a physical location.");
return;
}
Plugins__Spatial__infer_presence_nowhere(ox);
}
#line 190 "inform7/Chapter 14/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 599 "inform7/Chapter 14/Assert Propositions.w"
void cautiously_set_kind(inference_subject *inst, kind *k) {
if ((inst == NULL) || (k == NULL)) return;
if (Kinds__eq(k, K_thing)) return;
instance *instance_wo = World__Subjects__as_instance(inst);
if (instance_wo == NULL) return;
Data__Instances__set_kind(instance_wo, k);
}
#line 621 "inform7/Chapter 14/Assert Propositions.w"
specification *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 642 "inform7/Chapter 14/Assert Propositions.w"
inference_subject *subject_of_term(pcalc_term pt) {
if (pt.function) return NULL;
if (pt.variable >= 0) return current_interpretation_as_infs[pt.variable];
specification *spec = pt.constant;
if (Specifications__species_is(spec, CONSTANT_SPC))
return World__Subjects__from_specification(spec);
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
if (Specifications__Conditions__get_described_instance(spec))
return Data__Instances__as_subject(Specifications__Conditions__get_described_instance(spec));
if (Specifications__Conditions__get_described_kind(spec))
return Kinds__as_subject(Specifications__Conditions__get_described_kind(spec));
}
if (Specifications__species_is(spec, NONLOCAL_VARIABLE_SPC)) {
inference_subject *diversion =
Data__NonlocalVariables__get_alias(RETRIEVE_FROM_SPEC(spec, nonlocal_variable));
if (diversion) return diversion;
}
return NULL;
}
#line 673 "inform7/Chapter 14/Assert Propositions.w"
int Calculus__Propositions__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 693 "inform7/Chapter 14/Assert Propositions.w"
adjective_list_entry *ale = RETRIEVE_POINTER_adjective_list_entry(pl->predicate);
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(ale);
property *prn = Semantics__Adjectives__Phrases__has_EORP_meaning(aph);
if (prn == NULL) return FALSE;
}
#line 680 "inform7/Chapter 14/Assert Propositions.w"
; break;
case 2: return FALSE;
}
break;
default: return FALSE;
}
}
return TRUE;
}
#line 701 "inform7/Chapter 14/Assert Propositions.w"
int Calculus__Propositions__test_at_compile_time(pcalc_prop *prop, inference_subject *about) {
if (Calculus__Propositions__testable_at_compile_time(prop) == FALSE) return NOT_APPLICABLE;
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, prop) {
switch(pl->element) {
case KIND_ATOM:
{
#line 720 "inform7/Chapter 14/Assert Propositions.w"
;
}
#line 706 "inform7/Chapter 14/Assert Propositions.w"
; break;
case PREDICATE_ATOM:
switch (pl->arity) {
case 1:
{
#line 725 "inform7/Chapter 14/Assert Propositions.w"
adjective_list_entry *ale = RETRIEVE_POINTER_adjective_list_entry(pl->predicate);
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(ale);
property *prn = Semantics__Adjectives__Phrases__has_EORP_meaning(aph);
if (prn) {
possession_marker *adj = Properties__get_possession_marker(prn);
if (adj->possessed == FALSE) return FALSE;
}
}
#line 709 "inform7/Chapter 14/Assert Propositions.w"
; break;
}
break;
}
}
return TRUE;
}
#line 75 "inform7/Chapter 14/I6 Schemas.w"
i6_schema *Code__Schemas__new(char *fmt, ...) {
va_list ap; /* the variable argument list signified by the dots */
char temp[MAX_I6_SCHEMA_ATTEMPT];
{
#line 113 "inform7/Chapter 14/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 128 "inform7/Chapter 14/I6 Schemas.w"
p++;
switch (*p) {
case 'd': sprintf(temp+tn, "%d", va_arg(ap, int)); break;
case 'k':
{
#line 143 "inform7/Chapter 14/I6 Schemas.w"
kind *K = va_arg(ap, kind *);
TEMPORARY_STREAM;
Kinds__RuntimeIDs__compile_weak(TEMP, K);
strcpy(temp+tn, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 131 "inform7/Chapter 14/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 118 "inform7/Chapter 14/I6 Schemas.w"
; break;
default: temp[tn++] = *p; break;
}
}
temp[tn] = 0;
}
#line 78 "inform7/Chapter 14/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) internal_error("i6 schema overlong");
strcpy(sch->prototype, temp);
return sch;
}
#line 89 "inform7/Chapter 14/I6 Schemas.w"
void Code__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 113 "inform7/Chapter 14/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 128 "inform7/Chapter 14/I6 Schemas.w"
p++;
switch (*p) {
case 'd': sprintf(temp+tn, "%d", va_arg(ap, int)); break;
case 'k':
{
#line 143 "inform7/Chapter 14/I6 Schemas.w"
kind *K = va_arg(ap, kind *);
TEMPORARY_STREAM;
Kinds__RuntimeIDs__compile_weak(TEMP, K);
strcpy(temp+tn, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 131 "inform7/Chapter 14/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 118 "inform7/Chapter 14/I6 Schemas.w"
; break;
default: temp[tn++] = *p; break;
}
}
temp[tn] = 0;
}
#line 92 "inform7/Chapter 14/I6 Schemas.w"
;
va_end(ap); /* macro to end variable argument processing */
if (Platform__strlen(temp) >= MAX_I6_SCHEMA_LENGTH) internal_error("i6 schema overlong");
strcpy(sch->prototype, temp);
}
#line 101 "inform7/Chapter 14/I6 Schemas.w"
void Code__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 113 "inform7/Chapter 14/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 128 "inform7/Chapter 14/I6 Schemas.w"
p++;
switch (*p) {
case 'd': sprintf(temp+tn, "%d", va_arg(ap, int)); break;
case 'k':
{
#line 143 "inform7/Chapter 14/I6 Schemas.w"
kind *K = va_arg(ap, kind *);
TEMPORARY_STREAM;
Kinds__RuntimeIDs__compile_weak(TEMP, K);
strcpy(temp+tn, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 131 "inform7/Chapter 14/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 118 "inform7/Chapter 14/I6 Schemas.w"
; break;
default: temp[tn++] = *p; break;
}
}
temp[tn] = 0;
}
#line 104 "inform7/Chapter 14/I6 Schemas.w"
;
va_end(ap); /* macro to end variable argument processing */
if (Platform__strlen(temp) >= MAX_I6_SCHEMA_LENGTH) internal_error("i6 schema overlong");
strcpy(sch->prototype + Platform__strlen(sch->prototype), temp);
}
#line 153 "inform7/Chapter 14/I6 Schemas.w"
int Code__Schemas__empty(i6_schema *sch) {
if (sch == NULL) return TRUE;
if (sch->prototype[0] == 0) return TRUE;
return FALSE;
}
#line 164 "inform7/Chapter 14/I6 Schemas.w"
void Code__Schemas__expand(i6_schema *sch, OUTPUT_STREAM, pcalc_term *pt1, pcalc_term *pt2) {
STREAM *save_dl = dl;
if (OUT == NULL) return;
TEMPORARY_STREAM;
if (OUT == dl) dl = TEMP;
sch_expand_inner(sch, TEMP, pt1, NULL, pt2, NULL);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
dl = save_dl;
}
#line 178 "inform7/Chapter 14/I6 Schemas.w"
void Code__Schemas__expand_textual(i6_schema *sch, OUTPUT_STREAM, char *str1, char *str2) {
STREAM *save_dl = dl;
if (OUT == NULL) return;
TEMPORARY_STREAM;
if (OUT == dl) dl = TEMP;
sch_expand_inner(sch, TEMP, NULL, str1, NULL, str2);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
dl = save_dl;
}
#line 192 "inform7/Chapter 14/I6 Schemas.w"
void 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");
sch_type_parameter(pt1);
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 222 "inform7/Chapter 14/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)
Text__print_raw_text_within_i6_literal(OUT, current_sentence->word_ref1, current_sentence->word_ref2);
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);
specification *spec_A = NULL, *spec_B = NULL;
Specifications__Values__extract_pair(pt2->constant, &spec_A, &spec_B);
if (!((Kinds__uses_pointer_values(req_A)) && (Kinds__definite(req_A))))
req_A = NULL;
if (!((Kinds__uses_pointer_values(req_B)) && (Kinds__definite(req_B))))
req_B = NULL;
Specifications__compile_to_kind(OUT, spec_A, req_A);
WRITE(", ");
Specifications__compile_to_kind(OUT, spec_B, req_B);
break;
}
}
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;
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) &&
(Specifications__Values__is_actual_CONSTANT_of_kind(pt1->constant, K_response))) {
adopted_rule_for_compilation =
Code__Rules__from_specification(pt1->constant);
adopted_marker_for_compilation =
Data__Strings__get_marker_from_response_spec(pt1->constant);
LOG("Okay $S and %d\n", pt1->constant, adopted_marker_for_compilation);
}
kind *K = NULL;
if (cast_to_kind_of_other_term) K = pt1->term_checked_as_kind;
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 210 "inform7/Chapter 14/I6 Schemas.w"
;
continue;
}
WRITE("%c", schematic_text[i]);
}
END_COMPILATION_MODE;
}
#line 307 "inform7/Chapter 14/I6 Schemas.w"
void 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__RuntimeIDs__compile_weak(OUT, pt->term_checked_as_kind);
} else if (give_comparison_routine) {
if (pt) {
char *cr = Kinds__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__cast_call(OUT, pt->term_checked_as_kind, cast_to);
pcalc_term cpt = *pt;
if ((dereference_property) &&
(Specifications__Values__is_actual_CONSTANT(cpt.constant))) {
kind *K = Specifications__evaluates_to(cpt.constant);
if (Kinds__get_construct(K) == CON_property) {
cpt = Calculus__Terms__new_constant(
Specifications__Storage__new_PROPERTY_VALUE(
Specifications__copy(cpt.constant),
Specifications__Values__new_self_object_constant()));
}
}
Calculus__Terms__compile(OUT, cpt);
if (casting) WRITE(")");
}
}
}
#line 349 "inform7/Chapter 14/I6 Schemas.w"
void sch_type_parameter(pcalc_term *pt) {
if ((pt) && (pt->constant) && (pt->term_checked_as_kind == NULL))
pt->term_checked_as_kind = Specifications__evaluates_to(pt->constant);
}
#line 357 "inform7/Chapter 14/I6 Schemas.w"
void Code__Schemas__log(i6_schema *sch) {
if (sch == NULL) LOG("<null schema>");
else LOG("<schema: %s>", sch->prototype);
}
void Code__Schemas__log_applied(i6_schema *sch, pcalc_term *pt1) {
if (sch == NULL) { LOG("<null schema>"); return; }
Code__Schemas__expand(sch, dl, pt1, NULL);
}
#line 61 "inform7/Chapter 14/Compile Atoms.w"
void Calculus__Atoms__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 79 "inform7/Chapter 14/Compile Atoms.w"
asch = i6_schema_of_atom(&sch, pl, task);
if (asch.schema == NULL) {
if (problem_count == 0)
{
#line 90 "inform7/Chapter 14/Compile Atoms.w"
LOG("Failed on task: $o\n", pl);
if (task == TEST_ATOM_TASK)
Problems__sentence_problem(_P_(BelievedImpossible),
"this is not a condition I am able to test",
"or at any rate not during play.");
else
Problems__sentence_problem(_P_(C14CantForceRelation),
"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 82 "inform7/Chapter 14/Compile Atoms.w"
;
return;
}
{
#line 104 "inform7/Chapter 14/Compile Atoms.w"
if ((asch.involves_action_variables) &&
(Code__Frames__used_for_past_tense()) &&
(suppress_C14ActionVarsPastTense == FALSE)) {
if (problem_count == 0)
Problems__sentence_problem(_P_(C14ActionVarsPastTense),
"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 85 "inform7/Chapter 14/Compile Atoms.w"
;
}
#line 72 "inform7/Chapter 14/Compile Atoms.w"
;
{
#line 128 "inform7/Chapter 14/Compile Atoms.w"
if (task == TEST_ATOM_TASK) {
WRITE("(");
if (asch.negate_schema) WRITE("~~(");
}
Code__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 73 "inform7/Chapter 14/Compile Atoms.w"
;
}
#line 145 "inform7/Chapter 14/Compile Atoms.w"
annotated_i6_schema i6_schema_of_atom(i6_schema *sch, pcalc_prop *pl, int task) {
annotated_i6_schema asch;
Code__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 = atom_involves_action_variables(pl);
switch(pl->element) {
case CALLED_ATOM:
{
#line 184 "inform7/Chapter 14/Compile Atoms.w"
switch(task) {
case TEST_ATOM_TASK: {
int w1, w2;
Calculus__Atoms__CALLED_get_name(pl, &w1, &w2);
Code__Schemas__modify(sch, "%s=(*1), true",
Code__LocalVariables__lvalue(
Code__LocalVariables__ensure_called_local(w1, w2, pl->assert_kind)));
return asch;
}
default: asch.schema = NULL; return asch;
}
}
#line 155 "inform7/Chapter 14/Compile Atoms.w"
;
case KIND_ATOM:
{
#line 205 "inform7/Chapter 14/Compile Atoms.w"
switch(task) {
case TEST_ATOM_TASK:
if (Kinds__lt(pl->assert_kind, K_object))
Code__Schemas__modify(sch, "*1 ofclass %s",
Kinds__I6_classname(pl->assert_kind));
else
Code__Schemas__modify(sch, "true");
return asch;
case NOW_ATOM_TRUE_TASK:
case NOW_ATOM_FALSE_TASK:
if (suppress_C14CantChangeKind == FALSE) {
Problems__sentence_problem(_P_(C14CantChangeKind),
"the kind of something is fixed",
"and cannot be changed during play with a 'now'.");
asch.schema = NULL;
} else Code__Schemas__modify(sch, " ");
return asch;
}
}
#line 156 "inform7/Chapter 14/Compile Atoms.w"
;
case EVERYWHERE_ATOM:
{
#line 229 "inform7/Chapter 14/Compile Atoms.w"
switch(task) {
case TEST_ATOM_TASK:
Code__Schemas__modify(sch, "BackdropEverywhere(*1)");
return asch;
case NOW_ATOM_TRUE_TASK:
Code__Schemas__modify(sch, "MoveObject(*1, FoundEverywhere); MoveFloatingObjects();");
return asch;
case NOW_ATOM_FALSE_TASK:
Problems__sentence_problem(_P_(C14CantChangeEverywhere),
"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 157 "inform7/Chapter 14/Compile Atoms.w"
;
case NOWHERE_ATOM:
{
#line 247 "inform7/Chapter 14/Compile Atoms.w"
switch(task) {
case TEST_ATOM_TASK:
Code__Schemas__modify(sch, "LocationOf(*1) == nothing");
return asch;
case NOW_ATOM_TRUE_TASK:
Code__Schemas__modify(sch, "RemoveFromPlay(*1);");
return asch;
case NOW_ATOM_FALSE_TASK:
Code__Schemas__modify(sch, "MoveObject(*1, real_location, 1, false);");
return asch;
}
}
#line 158 "inform7/Chapter 14/Compile Atoms.w"
;
case HERE_ATOM:
{
#line 263 "inform7/Chapter 14/Compile Atoms.w"
switch(task) {
case TEST_ATOM_TASK:
Code__Schemas__modify(sch, "LocationOf(*1) == location");
return asch;
case NOW_ATOM_TRUE_TASK:
case NOW_ATOM_FALSE_TASK:
Problems__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 159 "inform7/Chapter 14/Compile Atoms.w"
;
case PREDICATE_ATOM:
switch(pl->arity) {
case 1:
{
#line 279 "inform7/Chapter 14/Compile Atoms.w"
int atask = 0; /* redundant assignment to appease |gcc -O2| */
adjective_list_entry *tr = RETRIEVE_POINTER_adjective_list_entry(pl->predicate);
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(tr);
if (Specifications__Conditions__adjective_used_positively(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__evaluates_to(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 = Semantics__Adjectives__Phrases__get_i6_schema(aph, pl->terms[0].term_checked_as_kind, atask);
return asch;
}
#line 162 "inform7/Chapter 14/Compile Atoms.w"
;
case 2:
{
#line 301 "inform7/Chapter 14/Compile Atoms.w"
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(pl->predicate);
binary_predicate *bp_to_assert = NULL;
{
#line 313 "inform7/Chapter 14/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 304 "inform7/Chapter 14/Compile Atoms.w"
;
asch.schema = Semantics__BPs__get_i6_schema(task, bp_to_assert, &asch);
return asch;
}
#line 163 "inform7/Chapter 14/Compile Atoms.w"
;
}
}
asch.schema = NULL; /* signal that the atom cannot be compiled simply */
return asch;
}
#line 329 "inform7/Chapter 14/Compile Atoms.w"
int atom_involves_action_variables(pcalc_prop *pl) {
int i;
for (i=0; i<pl->arity; i++) {
specification *operand = Calculus__Terms__constant_underlying(&(pl->terms[i]));
if (Plugins__Parsing__is_an_action_variable(operand)) return TRUE;
}
return FALSE;
}
#line 341 "inform7/Chapter 14/Compile Atoms.w"
annotated_i6_schema Calculus__Atoms__blank_asch(void) {
annotated_i6_schema asch;
asch.schema = Code__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 52 "inform7/Chapter 14/Deciding to Defer.w"
int no_further_deferrals = FALSE;
void Calculus__Deferrals__allow_no_further_deferrals(void) {
no_further_deferrals = TRUE;
}
#line 61 "inform7/Chapter 14/Deciding to Defer.w"
pcalc_prop_deferral *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 76 "inform7/Chapter 14/Deciding to Defer.w"
pcalc_prop *cache_loop_proposition = NULL;
pcalc_prop_deferral *cache_loop_pdef = NULL;
pcalc_prop_deferral *defer_loop_domain(pcalc_prop *prop) {
pcalc_prop_deferral *pdef;
if (prop == cache_loop_proposition) return cache_loop_pdef;
pdef = new_deferred_proposition(prop, LOOP_DOMAIN_DEFER);
cache_loop_proposition = prop;
cache_loop_pdef = pdef;
return pdef;
}
#line 93 "inform7/Chapter 14/Deciding to Defer.w"
int Calculus__Deferrals__compile_deferred_description_test(specification *spec) {
Specifications__Conditions__convert_docket_to_proposition(spec);
pcalc_prop *prop = Specifications__get_proposition(spec);
if (Calculus__Propositions__contains_callings(prop)) {
Problems__sentence_problem(_P_(C14CantCallDeferredDescs),
"'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 = new_deferred_proposition(prop, CONDITION_DEFER);
return pdef->allocation_id;
}
}
#line 118 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_test_of_proposition(OUTPUT_STREAM,
specification *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 155 "inform7/Chapter 14/Deciding to Defer.w"
pcalc_prop_deferral *pdef;
Code__LocalVariables__begin_condition(OUT);
{
#line 167 "inform7/Chapter 14/Deciding to Defer.w"
if (Calculus__Propositions__is_a_group(prop, NEGATION_OPEN_ATOM)) {
prop = Calculus__Propositions__remove_topmost_group(prop);
WRITE("~~");
}
}
#line 157 "inform7/Chapter 14/Deciding to Defer.w"
;
pdef = new_deferred_proposition(prop, CONDITION_DEFER);
{
#line 197 "inform7/Chapter 14/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__compile(OUT, substitution);
}
WRITE(")");
}
#line 159 "inform7/Chapter 14/Deciding to Defer.w"
;
retrieve_callings(OUT, prop, TRUE);
Code__LocalVariables__end_condition(OUT);
}
#line 128 "inform7/Chapter 14/Deciding to Defer.w"
;
} else {
if (substitution) Calculus__Propositions__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(OUT, TEST_ATOM_TASK, pl, TRUE); break;
}
}
}
WRITE(")");
}
#line 232 "inform7/Chapter 14/Deciding to Defer.w"
void 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 268 "inform7/Chapter 14/Deciding to Defer.w"
int w1, w2;
Calculus__Atoms__CALLED_get_name(pl, &w1, &w2);
local = Code__LocalVariables__ensure_called_local(w1, w2, pl->assert_kind);
}
#line 239 "inform7/Chapter 14/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",
Code__LocalVariables__lvalue(local), calling_count++);
if (condition_context) Code__LocalVariables__add_calling_to_condition(local);
break;
}
}
}
if (calling_count > 0) {
if (condition_context) WRITE(", true)");
else WRITE(", deferred_calling_list-->26");
}
}
#line 258 "inform7/Chapter 14/Deciding to Defer.w"
void 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 276 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_test_if_var_matches_description(OUTPUT_STREAM,
specification *var, specification *matches) {
if (matches == NULL) internal_error("VMD against null description");
if (var == NULL) internal_error("VMD on null variable");
if ((Specifications__Storage__get_storage_form(var) != NONLOCAL_VARIABLE_SPC) &&
(Specifications__Storage__get_storage_form(var) != LOCAL_VARIABLE_SPC))
internal_error("VMD on non-variable");
LOG_INDENT;
pcalc_prop *prop = Calculus__Propositions__from_spec(matches, FALSE);
kind *K = Specifications__evaluates_to(var);
prop = Calculus__Propositions__concatenate(
Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0)), prop);
LOGIF(DESCRIPTION_COMPILATION, "[VMD: $S ($u) matches $D]\n", var, K, prop);
if (Calculus__Propositions__type_check(prop,
Calculus__Propositions__tc_no_problem_reporting()) == NEVER_MATCH) {
WRITE("(false)");
} else {
Calculus__Deferrals__compile_test_of_proposition(OUT, var, prop);
}
LOG_OUTDENT;
}
#line 321 "inform7/Chapter 14/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 357 "inform7/Chapter 14/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__sentence_problem(_P_(C14CantForceExistence),
"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__sentence_problem(_P_(C14CantForceGeneralised),
"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__sentence_problem(_P_(C14CantForceCalling),
"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 327 "inform7/Chapter 14/Deciding to Defer.w"
;
if (quantifier_count > 0) {
pcalc_prop_deferral *pdef = 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(OUT,
(parity)?NOW_ATOM_TRUE_TASK:NOW_ATOM_FALSE_TASK, pl, with_semicolon);
break;
}
}
}
}
#line 421 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_multiple_use_proposition(OUTPUT_STREAM,
specification *spec, kind *K) {
int negate = FALSE;
quantifier *q = Specifications__Conditions__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__handmade_problem(_P_(C14BadQuantifierInDescription));
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, FALSE);
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__type_check(prop,
Calculus__Propositions__tc_no_problem_reporting()) == NEVER_MATCH) return;
specification *example = NULL;
if (Calculus__Deferrals__detect_locals(prop, &example) > 0) {
LOG("Offending proposition: $D\n", prop);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, example->word_ref1, example->word_ref2);
Problems__handmade_problem(_P_(C14LocalInDescription));
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 = new_deferred_proposition(prop, MULTIPURPOSE_DEFER);
WRITE("Prop_%d", pdef->allocation_id);
}
}
#line 491 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_number_of_S(OUTPUT_STREAM, specification *spec) {
if (spec_is_variable_of_kind_description(spec)) {
WRITE("(");
Specifications__compile(OUT, spec);
WRITE(")(%d)", NUMBER_OF_DUSAGE);
} else {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec, FALSE);
Calculus__Deferrals__prop_verify_descriptive(prop, "a number of things matching a description", spec);
compile_call_to_deferred_desc(OUT, prop, NUMBER_OF_DEFER, NULL_GENERAL_POINTER, NULL);
}
}
#line 506 "inform7/Chapter 14/Deciding to Defer.w"
int spec_is_variable_of_kind_description(specification *spec) {
if ((Specifications__family_is(spec, STORAGE_FMY)) &&
(Kinds__get_construct(Specifications__evaluates_to(spec)) == CON_description))
return TRUE;
return FALSE;
}
void compile_call_to_deferred_desc(OUTPUT_STREAM, pcalc_prop *prop,
int reason, general_pointer data, kind *K) {
pcalc_prop_deferral *pdef = new_deferred_proposition(prop, reason);
pdef->defn_ref = data;
WRITE("(");
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(",");
Code__Frames__compile_allocation(OUT, K);
WRITE(",");
Kinds__RuntimeIDs__compile_strong(OUT, Kinds__unary_construction_material(K));
}
WRITE(")");
retrieve_callings(OUT, prop, FALSE);
WRITE(")");
}
#line 535 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_list_of_S(OUTPUT_STREAM, specification *spec, kind *K) {
if (spec_is_variable_of_kind_description(spec)) {
WRITE("(LIST_OF_TY_Desc(");
Code__Frames__compile_allocation(OUT, K);
WRITE(",");
Specifications__compile(OUT, spec);
WRITE(",");
Kinds__RuntimeIDs__compile_strong(OUT, Kinds__unary_construction_material(K));
WRITE("))");
} else {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec, FALSE);
Calculus__Deferrals__prop_verify_descriptive(prop, "a list of things matching a description", spec);
compile_call_to_deferred_desc(OUT, prop, LIST_OF_DEFER, NULL_GENERAL_POINTER, K);
}
}
#line 554 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_random_of_S(OUTPUT_STREAM, specification *spec) {
if (Specifications__Values__is_actual_CONSTANT_construction(spec, CON_description)) {
kind *K = Specifications__get_kind(spec);
K = Kinds__unary_construction_material(K);
if ((K) && (Kinds__is_an_enumeration(K)) &&
(Specifications__get_proposition(spec) == NULL) &&
(Kinds__lt(Specifications__Conditions__get_described_kind(spec),
K_object) == FALSE) &&
(Specifications__Conditions__get_described_instance(spec) == NULL) &&
(Specifications__Conditions__number_of_adjectives_applied_to(spec) == 0)) {
WRITE("R_%s()", Kinds__get_name_of_printing_rule(K));
return;
}
}
if (spec_is_variable_of_kind_description(spec)) {
WRITE("(");
Specifications__compile(OUT, spec);
WRITE(")(%d)", RANDOM_OF_DUSAGE);
} else {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec, FALSE);
Calculus__Deferrals__prop_verify_descriptive(prop, "a random thing matching a description", spec);
kind *K = Calculus__Propositions__describes_kind(prop);
if ((K) && (Kinds__compile_domain_possible(K) == FALSE))
Problems__sentence_problem(_P_(C14RandomImpossible),
"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
compile_call_to_deferred_desc(OUT, prop, RANDOM_OF_DEFER, NULL_GENERAL_POINTER, NULL);
}
}
#line 591 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_total_of_S(OUTPUT_STREAM, property *prn, specification *spec) {
if (prn == NULL) internal_error("total of on non-property");
if (spec_is_variable_of_kind_description(spec)) {
WRITE("(property_to_be_totalled=%s,(", Properties__get_translation(prn));
Specifications__compile(OUT, spec);
WRITE(")(%d))", TOTAL_DUSAGE);
} else {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec, FALSE);
Calculus__Deferrals__prop_verify_descriptive(prop,
"a total property value for things matching a description", spec);
compile_call_to_deferred_desc(OUT, prop, TOTAL_DEFER,
STORE_POINTER_property(prn), NULL);
}
}
#line 610 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_substitution_test(OUTPUT_STREAM, specification *in,
specification *spec) {
if (spec_is_variable_of_kind_description(spec)) {
WRITE("(");
Specifications__compile(OUT, spec);
WRITE(")(%d,", CONDITION_DUSAGE);
Specifications__compile(OUT, in);
WRITE(")");
} else {
Calculus__Deferrals__compile_test_of_proposition(OUT,
in, Calculus__Propositions__from_spec(spec, FALSE));
}
}
#line 627 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_substitution_now(OUTPUT_STREAM, specification *in,
specification *spec) {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec, FALSE);
Calculus__Propositions__substitute_var_0_in(prop, in);
Calculus__Propositions__type_check(prop,
Calculus__Propositions__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 647 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_extremal_of_S(OUTPUT_STREAM, specification *spec,
property *prn, int sign) {
if (prn == NULL) internal_error("extremal of on non-property");
if (spec_is_variable_of_kind_description(spec)) {
WRITE("(property_to_be_totalled=%s,property_loop_sign=%d,(",
Properties__get_translation(prn), sign);
Specifications__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, FALSE);
Calculus__Deferrals__prop_verify_descriptive(prop,
"an extreme case of something matching a description", spec);
compile_call_to_deferred_desc(OUT, prop, EXTREMAL_DEFER,
STORE_POINTER_measurement_definition(mdef_found), NULL);
}
}
}
#line 696 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_repeat_through_domain_S(OUTPUT_STREAM, specification *spec,
local_variable *v1) {
kind *DK = Specifications__get_kind_referred_to(spec);
if (Kinds__get_construct(DK) != CON_description)
internal_error("repeat through non-description");
kind *K = Kinds__unary_construction_material(DK);
local_variable *v2 = Code__LocalVariables__new(-1, -1, K);
Code__Frames__Blocks__set_scope_to_block_about_to_open(v1);
Code__Frames__Blocks__set_scope_to_block_about_to_open(v2);
char val_var[32], aux_var[32];
sprintf(val_var, "%s", Code__LocalVariables__lvalue(v1));
sprintf(aux_var, "%s", Code__LocalVariables__lvalue(v2));
if (Kinds__le(K, K_object)) {
pcalc_prop *domain_prop = NULL; int use_as_is = FALSE;
if (spec_is_variable_of_kind_description(spec)) use_as_is = TRUE;
else {
domain_prop = Calculus__Propositions__from_spec(spec, FALSE);
if (Calculus__Propositions__contains_callings(domain_prop))
Problems__sentence_problem(_P_(C14CalledInRepeat),
"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) compile_repeat_call(OUT, spec, NULL);
else compile_repeat_domain(OUT, domain_prop, NULL);
WRITE(", %s=", aux_var);
if (use_as_is) compile_repeat_call(OUT, spec, v1);
else compile_repeat_domain(OUT, domain_prop, v1);
WRITE(": %s: %s=%s, %s=", val_var, val_var, aux_var, aux_var);
if (use_as_is) compile_repeat_call(OUT, spec, v2);
else compile_repeat_domain(OUT, domain_prop, v2);
WRITE(")");
} else {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
i6_schema loop_schema;
if (Kinds__write_loop_schema(&loop_schema, K, FALSE)) {
Code__Schemas__expand_textual(&loop_schema, OUT, val_var, aux_var);
if (Specifications__family_is(spec, STORAGE_FMY) == FALSE) {
Specifications__Conditions__convert_docket_to_proposition(spec);
if (Specifications__get_proposition(spec)) {
WRITE("if (");
Calculus__Deferrals__compile_test_of_proposition(OUT,
Specifications__Storage__new_LOCAL_VARIABLE(-1, -1, v1),
Specifications__get_proposition(spec));
WRITE(") ");
}
} else {
WRITE("if("); Specifications__compile(OUT, spec);
WRITE("(%d, ", CONDITION_DUSAGE);
Specifications__compile(OUT,
Specifications__Storage__new_LOCAL_VARIABLE(-1, -1, v1));
WRITE(")) ");
}
} else
Problems__sentence_problem(_P_(C14BadRepeatDomain),
"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 777 "inform7/Chapter 14/Deciding to Defer.w"
void compile_repeat_call(OUTPUT_STREAM, specification *spec, local_variable *fromv) {
WRITE("(");
Specifications__compile(OUT, spec);
WRITE(")(%d,", LOOP_DOMAIN_DUSAGE);
if (fromv) WRITE("%s", Code__LocalVariables__lvalue(fromv)); else WRITE("0");
WRITE(")");
}
#line 790 "inform7/Chapter 14/Deciding to Defer.w"
void compile_repeat_domain(OUTPUT_STREAM, pcalc_prop *prop, local_variable *fromv) {
pcalc_prop_deferral *pdef = 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", Code__LocalVariables__lvalue(fromv)); else WRITE("0");
WRITE(")");
}
#line 802 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__compile_loop_over_list_S(OUTPUT_STREAM, specification *spec, local_variable *v1) {
local_variable *index_in_list = Code__LocalVariables__new(-1, -1, K_number);
local_variable *copy_of_list = Code__LocalVariables__new(-1, -1, K_number);
kind *K = Specifications__evaluates_to(spec);
Code__Frames__Blocks__set_scope_to_block_about_to_open(v1);
Code__LocalVariables__set_kind(v1, Kinds__unary_construction_material(K));
Code__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", Code__LocalVariables__lvalue(v1));
sprintf(aux_var, "%s", Code__LocalVariables__lvalue(index_in_list));
sprintf(cop_var, "%s", Code__LocalVariables__lvalue(copy_of_list));
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
WRITE("for (%s=", cop_var);
Specifications__compile(OUT, spec);
WRITE(", %s=1, %s=LIST_OF_TY_GetItem(%s, %s, true): ", aux_var, val_var, cop_var, aux_var);
WRITE("%s<=LIST_OF_TY_GetLength(%s): ", aux_var, cop_var);
WRITE("%s++, %s=LIST_OF_TY_GetItem(%s, %s, true))", aux_var, val_var, cop_var, aux_var);
END_COMPILATION_MODE;
}
#line 832 "inform7/Chapter 14/Deciding to Defer.w"
void Calculus__Deferrals__prop_verify_descriptive(pcalc_prop *prop, char *billing,
specification *constructor) {
if (constructor == NULL) internal_error("description with null constructor");
/* best guess at the text to quote in any problem message */
int ew1 = constructor->word_ref1, ew2 = constructor->word_ref2;
if ((ew1 < 0) && (Specifications__get_argc(constructor) >= 1) && (Specifications__get_argument(constructor, 0))) {
ew1 = Specifications__get_argument(constructor, 0)->word_ref1;
ew2 = Specifications__get_argument(constructor, 0)->word_ref2;
}
if (Calculus__Propositions__is_well_formed(prop) == FALSE)
internal_error("malformed proposition in description verification");
int N = Calculus__Variables__number_free(prop);
if (N == 1)
Calculus__Propositions__type_check(prop,
Calculus__Propositions__tc_problem_reporting(ew1, ew2,
"involve a range of objects matching a description"));
if (N > 1) {
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, billing);
Problems__quote_words(3, ew1, ew2);
Problems__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_words(3, ew1, ew2);
Problems__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 14/Cinders and Deferrals.w"
pcalc_prop_deferral *current_pdef = NULL; /* used only in this section */
#line 63 "inform7/Chapter 14/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 =
cind_find_in_term(OUT, &(pl->terms[i]), cinder_number, &started);
current_pdef = save_current_pdef;
return cinder_number;
}
int 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 cind_find_in_term(OUT, &(pt->function->fn_of), cinder_number, started);
if (pt->constant) {
if (spec_needs_to_be_cindered(pt->constant)) {
pt->cinder = cinder_number++;
if (*started) WRITE(",");
Specifications__compile(OUT, pt->constant);
current_pdef->cinder_kinds[pt->cinder] =
Specifications__evaluates_to(pt->constant);
*started = TRUE;
} else pt->cinder = -1;
}
return cinder_number;
}
#line 115 "inform7/Chapter 14/Cinders and Deferrals.w"
int spec_needs_to_be_cindered(specification *spec) {
if (Specifications__species_is(spec, CONSTANT_SPC)) return FALSE;
if (Specifications__Storage__is_global_variable(spec)) return FALSE;
return TRUE;
}
#line 131 "inform7/Chapter 14/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 = cind_declare_in(cinder_number, &(pl->terms[i]));
current_pdef = save_current_pdef;
}
int cind_declare_in(int cinder_number, pcalc_term *pt) {
if (pt->function)
return cind_declare_in(cinder_number, &(pt->function->fn_of));
if ((pt->constant) && (pt->cinder >= 0))
if (Specifications__species_is(pt->constant, CONSTANT_SPC) == FALSE) {
char cinder_name[32];
sprintf(cinder_name, "const_%d", cinder_number++);
Code__LocalVariables__add_named_call(cinder_name);
}
return cinder_number;
}
#line 163 "inform7/Chapter 14/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 (Specifications__is_phrasal(pt.constant))
Specifications__Matching__check_without_expectations(pt.constant);
return Specifications__evaluates_to(pt.constant);
}
if (pt.function) return K_object;
internal_error("Broken pcalc term");
return NULL;
}
#line 197 "inform7/Chapter 14/Cinders and Deferrals.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) {
WRITE("const_%d", pt.cinder);
} else {
if (Specifications__is_phrasal(pt.constant))
Specifications__Matching__check_without_expectations(pt.constant);
Specifications__compile(OUT, pt.constant);
}
return;
}
if (pt.function) {
i6_schema *fn;
binary_predicate *bp = (pt.function)->bp;
fn = Semantics__BPs__get_term_as_function_of_other(bp, 0);
if (fn == NULL) fn = Semantics__BPs__get_term_as_function_of_other(bp, 1);
if (fn == NULL) internal_error("Function of non-functional predicate");
Code__Schemas__expand(fn, OUT, &(pt.function->fn_of), NULL);
return;
}
internal_error("Broken pcalc term");
}
#line 235 "inform7/Chapter 14/Cinders and Deferrals.w"
int Calculus__Deferrals__detect_locals(pcalc_prop *prop, specification **example) {
TRAVERSE_VARIABLE(pl);
int i, locals_count = 0;
TRAVERSE_PROPOSITION(pl, prop)
for (i=0; i<pl->arity; i++)
locals_count =
detect_local_in_term(&(pl->terms[i]), locals_count, example);
return locals_count;
}
int detect_local_in_term(pcalc_term *pt, int locals_count, specification **example) {
if (pt->function)
locals_count += detect_local_in_term(&(pt->function->fn_of), locals_count, example);
if (pt->constant)
locals_count += detect_local_in_spec(pt->constant, locals_count, example);
return locals_count;
}
int detect_local_in_spec(specification *spec, int locals_count, specification **example) {
int i;
if (spec == NULL) return locals_count;
if (Specifications__Storage__get_storage_form(spec) == LOCAL_VARIABLE_SPC) {
if ((example) && (*example == NULL)) *example = spec;
return ++locals_count;
}
if (Specifications__Storage__get_storage_form(spec) == NONLOCAL_VARIABLE_SPC) {
nonlocal_variable *nlv = RETRIEVE_FROM_SPEC(spec, nonlocal_variable);
if (Data__NonlocalVariables__is_global(nlv) == FALSE) {
if ((example) && (*example == NULL)) *example = spec;
return ++locals_count;
}
}
if (Specifications__is_phrasal(spec)) {
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_INVOCATION_LIST(inv, Specifications__invocation_list(spec)) {
specification *param;
LOOP_THROUGH_TOKENS_PARSED_IN_INV(inv, param)
locals_count +=
detect_local_in_spec(param, locals_count, example);
}
}
for (i=0; i<Specifications__get_argc(spec); i++)
locals_count +=
detect_local_in_spec(Specifications__get_argument(spec, i), locals_count, example);
return locals_count;
}
#line 16 "inform7/Chapter 14/Compile Deferred Propositions.w"
void 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 14/Compile Deferred Propositions.w"
void Calculus__Propositions__compile_remaining_deferred(OUTPUT_STREAM) {
Calculus__Propositions__compilation_coroutine(OUT);
}
pcalc_prop_deferral *latest_pcd = NULL;
int Calculus__Propositions__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 14/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 124 "inform7/Chapter 14/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 14/Compile Deferred Propositions.w"
;
{
#line 134 "inform7/Chapter 14/Compile Deferred Propositions.w"
LOGIF(PREDICATE_CALCULUS, "Compiling deferred proposition: %d: reason %d: $D\n",
pdef->allocation_id, pdef->reason, proposition);
compile_comment_about_deferral_reason(OUT, pdef->reason);
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 14/Compile Deferred Propositions.w"
;
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "Prop_%d", pdef->allocation_id);
OUT = Code__Routines__begin(OUT, i6_routine_identifier);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
{
#line 186 "inform7/Chapter 14/Compile Deferred Propositions.w"
int j, var_states[26], no_extras;
if (multipurpose_routine)
Code__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]);
Code__LocalVariables__add_internal_local(letter_var);
sprintf(letter_var, "%c_ix", pcalc_vars[j]);
Code__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);
Code__LocalVariables__add_internal_local(q_var);
sprintf(q_var, "qcn_%d", no_extras);
Code__LocalVariables__add_internal_local(q_var);
no_extras++;
}
{
#line 785 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (multipurpose_routine) {
Code__LocalVariables__add_internal_local("total");
Code__LocalVariables__add_internal_local("counter");
Code__LocalVariables__add_internal_local("selection");
Code__LocalVariables__add_internal_local("best");
Code__LocalVariables__add_internal_local("best_with");
} else {
switch (pdef->reason) {
case NUMBER_OF_DEFER:
Code__LocalVariables__add_internal_local("counter");
break;
case RANDOM_OF_DEFER:
Code__LocalVariables__add_internal_local("counter");
Code__LocalVariables__add_internal_local("selection");
break;
case TOTAL_DEFER:
Code__LocalVariables__add_internal_local("total");
break;
case LIST_OF_DEFER:
Code__LocalVariables__add_internal_local("counter");
Code__LocalVariables__add_internal_local("total");
Code__LocalVariables__add_named_call("list");
Code__LocalVariables__add_named_call("strong_kind");
break;
case EXTREMAL_DEFER:
Code__LocalVariables__add_internal_local("best");
Code__LocalVariables__add_internal_local("best_with");
break;
}
}
}
#line 214 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
WRITE(";\n");
}
#line 97 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
{
#line 220 "inform7/Chapter 14/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);
compile_comment_about_deferral_reason(OUT, reason);
INDENT;
{
#line 262 "inform7/Chapter 14/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 822 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
#line 268 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1018 "inform7/Chapter 14/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 = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 269 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1128 "inform7/Chapter 14/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 = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 270 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 846 "inform7/Chapter 14/Compile Deferred Propositions.w"
proposition = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 271 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 878 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("BlkValueWrite(list, LIST_ITEM_KOV_F, strong_kind);\n");
WRITE("total = LIST_OF_TY_GetLength(list);\n");
proposition = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 272 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 964 "inform7/Chapter 14/Compile Deferred Propositions.w"
proposition = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 273 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 924 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("selection = -1;\n");
WRITE("while (true) {\n");
INDENT;
WRITE("counter = 0;\n");
proposition = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 274 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
}
{
#line 369 "inform7/Chapter 14/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 414 "inform7/Chapter 14/Compile Deferred Propositions.w"
R_stack_reason[R_sp] = reason;
R_stack_parity[R_sp] = TRUE;
R_sp++;
}
#line 388 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
/* we now begin compiling the search code */
{
#line 460 "inform7/Chapter 14/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 548 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 552 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 468 "inform7/Chapter 14/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 548 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 552 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 472 "inform7/Chapter 14/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 = pl->calling_data;
if (quant != exists_quantifier)
{
#line 634 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (R_stack_reason[R_sp-1] == NOW_ASSERTION_DEFER)
{
#line 655 "inform7/Chapter 14/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 635 "inform7/Chapter 14/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 476 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
{
#line 587 "inform7/Chapter 14/Compile Deferred Propositions.w"
pl = 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 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 590 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
#line 477 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
break;
case DOMAIN_OPEN_ATOM:
{
#line 548 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 552 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 480 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
{
#line 426 "inform7/Chapter 14/Compile Deferred Propositions.w"
R_stack_reason[R_sp] = FILTER_DEFER;
R_stack_parity[R_sp] = TRUE;
R_sp++;
}
#line 481 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
break;
case DOMAIN_CLOSE_ATOM:
{
#line 548 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 552 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 484 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
{
#line 439 "inform7/Chapter 14/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 827 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("rtrue;\n");
}
#line 446 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1044 "inform7/Chapter 14/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 447 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1142 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("return %c;\n", pcalc_vars[0]);
}
#line 448 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 859 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 449 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 893 "inform7/Chapter 14/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 450 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 976 "inform7/Chapter 14/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 451 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 939 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter == selection) return %c;\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 452 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
}
}
#line 485 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
break;
case CALLED_ATOM:
{
#line 722 "inform7/Chapter 14/Compile Deferred Propositions.w"
C_stack_term[C_sp] = pl->terms[0];
C_stack_index[C_sp] = no_deferred_callings++;
C_sp++;
}
#line 488 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
break;
default:
if (R_stack_reason[R_sp-1] == NOW_ASSERTION_DEFER)
{
#line 570 "inform7/Chapter 14/Compile Deferred Propositions.w"
Calculus__Atoms__compile(OUT, (R_stack_parity[R_sp-1])?NOW_ATOM_TRUE_TASK:NOW_ATOM_FALSE_TASK, pl, TRUE);
WRITE("\n");
}
#line 492 "inform7/Chapter 14/Compile Deferred Propositions.w"
else
{
#line 537 "inform7/Chapter 14/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(OUT, TEST_ATOM_TASK, pl, TRUE);
}
#line 494 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
break;
}
}
{
#line 548 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 552 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 498 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
#line 390 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
while (Q_sp > 0)
{
#line 695 "inform7/Chapter 14/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 756 "inform7/Chapter 14/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 699 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
while (block_nesting > Q_stack_block_nesting[Q_sp])
{
#line 771 "inform7/Chapter 14/Compile Deferred Propositions.w"
OUTDENT;
WRITE("}\n");
block_nesting--;
}
#line 702 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
WRITE("if (");
Semantics__Quantifiers__compile_test(OUT, Q_stack_quantifier[Q_sp], Q_sp, Q_stack_parameter[Q_sp]);
WRITE(")");
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 707 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
#line 391 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
while (C_sp > 0)
{
#line 756 "inform7/Chapter 14/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 392 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
/* we are now at the magic match point |M| in the search code */
{
#line 439 "inform7/Chapter 14/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 827 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("rtrue;\n");
}
#line 446 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1044 "inform7/Chapter 14/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 447 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1142 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("return %c;\n", pcalc_vars[0]);
}
#line 448 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 859 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 449 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 893 "inform7/Chapter 14/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 450 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 976 "inform7/Chapter 14/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 451 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 939 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter == selection) return %c;\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 452 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
}
}
#line 394 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
while (block_nesting > 0)
{
#line 771 "inform7/Chapter 14/Compile Deferred Propositions.w"
OUTDENT;
WRITE("}\n");
block_nesting--;
}
#line 396 "inform7/Chapter 14/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 276 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
switch(reason) {
case NOW_ASSERTION_DEFER: break;
case CONDITION_DEFER:
{
#line 832 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("rfalse;\n");
}
#line 279 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1080 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return best_with;\n");
}
#line 280 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1147 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return nothing;\n");
}
#line 281 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 868 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return counter;\n");
}
#line 282 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 904 "inform7/Chapter 14/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 283 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 990 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return total;\n");
}
#line 284 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 951 "inform7/Chapter 14/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 285 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
}
}
#line 241 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
OUTDENT;
}
OUTDENT;
WRITE("}\n");
} else {
reason = pdef->reason;
{
#line 262 "inform7/Chapter 14/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 822 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
#line 268 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1018 "inform7/Chapter 14/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 = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 269 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1128 "inform7/Chapter 14/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 = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 270 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 846 "inform7/Chapter 14/Compile Deferred Propositions.w"
proposition = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 271 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 878 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("BlkValueWrite(list, LIST_ITEM_KOV_F, strong_kind);\n");
WRITE("total = LIST_OF_TY_GetLength(list);\n");
proposition = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 272 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 964 "inform7/Chapter 14/Compile Deferred Propositions.w"
proposition = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 273 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 924 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("selection = -1;\n");
WRITE("while (true) {\n");
INDENT;
WRITE("counter = 0;\n");
proposition = compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 274 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
}
{
#line 369 "inform7/Chapter 14/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 414 "inform7/Chapter 14/Compile Deferred Propositions.w"
R_stack_reason[R_sp] = reason;
R_stack_parity[R_sp] = TRUE;
R_sp++;
}
#line 388 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
/* we now begin compiling the search code */
{
#line 460 "inform7/Chapter 14/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 548 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 552 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 468 "inform7/Chapter 14/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 548 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 552 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 472 "inform7/Chapter 14/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 = pl->calling_data;
if (quant != exists_quantifier)
{
#line 634 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (R_stack_reason[R_sp-1] == NOW_ASSERTION_DEFER)
{
#line 655 "inform7/Chapter 14/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 635 "inform7/Chapter 14/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 476 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
{
#line 587 "inform7/Chapter 14/Compile Deferred Propositions.w"
pl = 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 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 590 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
#line 477 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
break;
case DOMAIN_OPEN_ATOM:
{
#line 548 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 552 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 480 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
{
#line 426 "inform7/Chapter 14/Compile Deferred Propositions.w"
R_stack_reason[R_sp] = FILTER_DEFER;
R_stack_parity[R_sp] = TRUE;
R_sp++;
}
#line 481 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
break;
case DOMAIN_CLOSE_ATOM:
{
#line 548 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 552 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 484 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
{
#line 439 "inform7/Chapter 14/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 827 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("rtrue;\n");
}
#line 446 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1044 "inform7/Chapter 14/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 447 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1142 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("return %c;\n", pcalc_vars[0]);
}
#line 448 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 859 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 449 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 893 "inform7/Chapter 14/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 450 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 976 "inform7/Chapter 14/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 451 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 939 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter == selection) return %c;\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 452 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
}
}
#line 485 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
break;
case CALLED_ATOM:
{
#line 722 "inform7/Chapter 14/Compile Deferred Propositions.w"
C_stack_term[C_sp] = pl->terms[0];
C_stack_index[C_sp] = no_deferred_callings++;
C_sp++;
}
#line 488 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
break;
default:
if (R_stack_reason[R_sp-1] == NOW_ASSERTION_DEFER)
{
#line 570 "inform7/Chapter 14/Compile Deferred Propositions.w"
Calculus__Atoms__compile(OUT, (R_stack_parity[R_sp-1])?NOW_ATOM_TRUE_TASK:NOW_ATOM_FALSE_TASK, pl, TRUE);
WRITE("\n");
}
#line 492 "inform7/Chapter 14/Compile Deferred Propositions.w"
else
{
#line 537 "inform7/Chapter 14/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(OUT, TEST_ATOM_TASK, pl, TRUE);
}
#line 494 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
break;
}
}
{
#line 548 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 552 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 498 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
#line 390 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
while (Q_sp > 0)
{
#line 695 "inform7/Chapter 14/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 756 "inform7/Chapter 14/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 699 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
while (block_nesting > Q_stack_block_nesting[Q_sp])
{
#line 771 "inform7/Chapter 14/Compile Deferred Propositions.w"
OUTDENT;
WRITE("}\n");
block_nesting--;
}
#line 702 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
WRITE("if (");
Semantics__Quantifiers__compile_test(OUT, Q_stack_quantifier[Q_sp], Q_sp, Q_stack_parameter[Q_sp]);
WRITE(")");
{
#line 764 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 707 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
#line 391 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
while (C_sp > 0)
{
#line 756 "inform7/Chapter 14/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 392 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
/* we are now at the magic match point |M| in the search code */
{
#line 439 "inform7/Chapter 14/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 827 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("rtrue;\n");
}
#line 446 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1044 "inform7/Chapter 14/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 447 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1142 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("return %c;\n", pcalc_vars[0]);
}
#line 448 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 859 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 449 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 893 "inform7/Chapter 14/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 450 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 976 "inform7/Chapter 14/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 451 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 939 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter == selection) return %c;\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 452 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
}
}
#line 394 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
while (block_nesting > 0)
{
#line 771 "inform7/Chapter 14/Compile Deferred Propositions.w"
OUTDENT;
WRITE("}\n");
block_nesting--;
}
#line 396 "inform7/Chapter 14/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 276 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
switch(reason) {
case NOW_ASSERTION_DEFER: break;
case CONDITION_DEFER:
{
#line 832 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("rfalse;\n");
}
#line 279 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1080 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return best_with;\n");
}
#line 280 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1147 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return nothing;\n");
}
#line 281 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 868 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return counter;\n");
}
#line 282 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 904 "inform7/Chapter 14/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 283 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 990 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return total;\n");
}
#line 284 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 951 "inform7/Chapter 14/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 285 "inform7/Chapter 14/Compile Deferred Propositions.w"
; break;
}
}
#line 248 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 98 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
{
#line 149 "inform7/Chapter 14/Compile Deferred Propositions.w"
if ((Code__LocalVariables__are_we_using_table_lookup()) && (!ct_locals_problem_thrown)) {
ct_locals_problem_thrown = TRUE;
Problems__sentence_problem(_P_(C14CantLookUpTableInDeferred),
"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 14/Compile Deferred Propositions.w"
;
{
#line 166 "inform7/Chapter 14/Compile Deferred Propositions.w"
if (negated_quantifier_found) {
Problems__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 14/Compile Deferred Propositions.w"
;
END_COMPILATION_MODE;
OUT = Code__Routines__end(OUT);
if (pdef->rtp_constant_needed)
{
#line 113 "inform7/Chapter 14/Compile Deferred Propositions.w"
WRITE("Constant PROP_SRC_%d = \"", pdef->allocation_id);
if (pdef->deferred_from)
Text__print_raw_text_within_i6_literal(OUT,
pdef->deferred_from->word_ref1, pdef->deferred_from->word_ref2);
else
WRITE("not sure where this came from");
WRITE("\";\n");
}
#line 105 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
current_pdef = save_current_pdef;
}
#line 62 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
N++;
}
return N;
}
#line 1215 "inform7/Chapter 14/Compile Deferred Propositions.w"
i6_schema loop_schema;
pcalc_prop *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 */
Code__Schemas__modify(&loop_schema, "objectloop (*1 ofclass Object)");
{
#line 1255 "inform7/Chapter 14/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 1280 "inform7/Chapter 14/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 1305 "inform7/Chapter 14/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) &&
(Semantics__BPs__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) &&
(Semantics__BPs__write_optimised_loop_schema(&loop_schema, bp))) {
second_term = pl->terms[1];
parent_optimised = TRUE;
proposition = Calculus__Propositions__delete_atom(proposition, pl_prev);
}
}
#line 1287 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
#line 1272 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
}
}
#line 1227 "inform7/Chapter 14/Compile Deferred Propositions.w"
;
if ((K) && (parent_optimised == FALSE)) { /* parent optimisation is stronger, so we prefer that */
if (Kinds__write_loop_schema(&loop_schema, K, TRUE) == FALSE) {
Code__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);
}
Code__Schemas__expand(&loop_schema, OUT, &var_term, &second_term);
return proposition;
}
#line 283 "inform7/Chapter 15/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 15/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 15/Kinds.w"
;
K->construct = con;
if (cache) *cache = K;
no_base_kinds_created++;
return K;
}
#line 313 "inform7/Chapter 15/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 15/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 15/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 15/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 15/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 15/Kinds.w"
;
K->construct = CON_KIND_VARIABLE;
K->kind_variable_number = N;
K->kc_args[0] = declaration;
return K;
}
#line 352 "inform7/Chapter 15/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 15/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 15/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 15/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 15/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 15/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 15/Kinds.w"
kind *Kinds__pair_kind(kind *X, kind *Y) {
return Kinds__binary_construction(CON_combination, X, Y);
}
#line 443 "inform7/Chapter 15/Kinds.w"
kind *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 *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 15/Kinds.w"
kind_constructor *Kinds__get_construct(kind *K) {
if (K) return K->construct;
return NULL;
}
#line 473 "inform7/Chapter 15/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 15/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 15/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 15/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 15/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 15/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 15/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__lt(K, K_object))) return K_object;
}
return K;
}
#line 607 "inform7/Chapter 15/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 15/Kinds.w"
int notable_linguistic_kinds_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 637 "inform7/Chapter 15/Kinds.w"
#line 649 "inform7/Chapter 15/Kinds.w"
int no_kinds_of_object = 1;
kind *Kinds__new_base(int w1, int w2, kind *super) {
PROTECTED_MODEL_PROCEDURE;
kind *K = Kinds__base_construction(
Kinds__Constructors__new(Kinds__get_construct(super), "", "#NEW"));
{
#line 689 "inform7/Chapter 15/Kinds.w"
inference_subject *revised = NULL;
if (w1 >= 0) Config__Plugins__Call__name_to_early_infs(w1, w2, &revised);
if (revised) {
World__Subjects__renew(revised,
Kinds__as_subject(super), KIND_SUB, STORE_POINTER_kind_constructor(K->construct), LIKELY_CE);
Kinds__set_subject(K, revised);
}
}
#line 655 "inform7/Chapter 15/Kinds.w"
;
if (Kinds__le(super, K_object))
World__Subjects__falls_within(Kinds__as_subject(K), Kinds__as_subject(super));
{
#line 700 "inform7/Chapter 15/Kinds.w"
unsigned int mc = KIND_SLOW_MC;
if (Kinds__le(super, K_object)) mc = NAMETAG_MC;
nametag *nt = Data__Nametags__new(w1, w2, 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__le(super, K_object))
Data__Nametags__set_range_number(nt, no_kinds_of_object++);
Kinds__Constructors__attach_nametag(K->construct, nt);
}
#line 660 "inform7/Chapter 15/Kinds.w"
;
if (parse_nt_against_word_range(notable_linguistic_kinds_NTM, w1, w2, NULL, NULL)) {
Kinds__Constructors__mark_as_linguistic(K->construct);
switch (most_recent_result) {
case 0: K_natural_language = K; Text__Languages__stock_nl_kind(K); break;
case 1: K_grammatical_gender = K; break;
}
}
if (parse_nt_against_word_range(property_name_NTM, w1, w2, NULL, NULL)) {
property *P = most_recent_result_p;
Properties__Valued__set_kind(P, K);
Data__Instances__make_kind_coincident(K, P);
if (Kinds__eq(K, K_grammatical_gender)) P_grammatical_gender = P;
}
Config__Plugins__Call__new_base_kind_notify(K, Kinds__get_name_in_template_code(K), w1, w2);
latest_base_kind_of_value = K;
LOGIF(KIND_CREATIONS, "Created base kind $u\n", K);
return K;
}
#line 724 "inform7/Chapter 15/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);
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("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__Constructors__known_name(char *sn) {
if (Kinds__known_constructor_name(sn)) return TRUE;
if (Kinds__known_kind_name(sn)) return TRUE;
return FALSE;
}
#line 116 "inform7/Chapter 15/Kind Checking.w"
int Kinds__le(kind *from, kind *to) {
if (test_kind_relation(from, to, FALSE) == ALWAYS_MATCH) return TRUE;
return FALSE;
}
int Kinds__lt(kind *from, kind *to) {
if (Kinds__eq(from, to)) return FALSE;
return Kinds__le(from, to);
}
#line 145 "inform7/Chapter 15/Kind Checking.w"
int Kinds__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__eq(K1->kc_args[i], K2->kc_args[i]) == FALSE)
return FALSE;
return TRUE;
}
#line 168 "inform7/Chapter 15/Kind Checking.w"
kind *Kinds__super(kind *K) {
if (Kinds__le(K, K_object)) {
inference_subject *infs = Kinds__as_subject(K);
return World__Subjects__as_kind(World__Subjects__narrowest_broader_subject(infs));
}
return NULL;
}
#line 182 "inform7/Chapter 15/Kind Checking.w"
kind *Kinds__max(kind *K1, kind *K2) {
if ((Kinds__uses_floating_point(K1) == FALSE) &&
(Kinds__uses_floating_point(K2)) &&
(Kinds__eq(Kinds__to_real(K1), K2)))
return K2;
if ((Kinds__uses_floating_point(K2) == FALSE) &&
(Kinds__uses_floating_point(K1)) &&
(Kinds__eq(Kinds__to_real(K2), K1)))
return K1;
return traverse_kind_poset(K1, K2, 1);
}
kind *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] = traverse_kind_poset(K1->kc_args[i], K2->kc_args[i], direction);
else
ka[i] = 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__le(K1, K2)) return (direction > 0)?K2:K1;
if (Kinds__le(K2, K1)) return (direction > 0)?K1:K2;
if (direction > 0) {
if ((Kinds__le(K1, K_object)) && (Kinds__le(K2, K_object))) {
kind *K;
for (K = K1; K; K = Kinds__super(K))
if (Kinds__le(K2, K))
return K;
}
}
}
return K_value;
}
#line 231 "inform7/Chapter 15/Kind Checking.w"
kind *Kinds__accumulative_max(kind *K1, kind *K2) {
if ((Kinds__definite(K1) == TRUE) && (Kinds__definite(K2) == FALSE) &&
(Kinds__compatible(K2, K1) == ALWAYS_MATCH)) return K1;
else if ((Kinds__definite(K2) == TRUE) && (Kinds__definite(K1) == FALSE) &&
(Kinds__compatible(K1, K2) == ALWAYS_MATCH)) return K2;
return Kinds__max(K1, K2);
}
#line 259 "inform7/Chapter 15/Kind Checking.w"
int Kinds__compatible(kind *from, kind *to) {
if (Kinds__eq(from, to)) return ALWAYS_MATCH;
LOGIF(KIND_CHECKING, "(Is the kind $u compatible with $u?", from, to);
switch(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__compatible"); return NEVER_MATCH;
}
#line 278 "inform7/Chapter 15/Kind Checking.w"
int test_kind_relation(kind *from, kind *to, int comp) {
if (Kinds__get_variable_number(to) > 0) {
kind *var_k = to, *other_k = from;
{
#line 366 "inform7/Chapter 15/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 401 "inform7/Chapter 15/Kind Checking.w"
switch(kind_checker_mode) {
case MATCH_KIND_VARIABLES_INFERRING_VALUES:
if (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 375 "inform7/Chapter 15/Kind Checking.w"
else
{
#line 422 "inform7/Chapter 15/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 (test_kind_relation(other_k, values_of_kind_variables[vn], comp) == NEVER_MATCH)
return NEVER_MATCH;
else
return ALWAYS_MATCH;
}
}
#line 377 "inform7/Chapter 15/Kind Checking.w"
;
}
}
}
#line 281 "inform7/Chapter 15/Kind Checking.w"
;
}
if (Kinds__get_variable_number(from) > 0) {
kind *var_k = from, *other_k = to;
{
#line 366 "inform7/Chapter 15/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 401 "inform7/Chapter 15/Kind Checking.w"
switch(kind_checker_mode) {
case MATCH_KIND_VARIABLES_INFERRING_VALUES:
if (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 375 "inform7/Chapter 15/Kind Checking.w"
else
{
#line 422 "inform7/Chapter 15/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 (test_kind_relation(other_k, values_of_kind_variables[vn], comp) == NEVER_MATCH)
return NEVER_MATCH;
else
return ALWAYS_MATCH;
}
}
#line 377 "inform7/Chapter 15/Kind Checking.w"
;
}
}
}
#line 285 "inform7/Chapter 15/Kind Checking.w"
;
}
{
#line 305 "inform7/Chapter 15/Kind Checking.w"
if (Kinds__eq(to, K_value)) return ALWAYS_MATCH;
if ((comp) && (Kinds__eq(from, K_value))) return ALWAYS_MATCH;
}
#line 287 "inform7/Chapter 15/Kind Checking.w"
;
{
#line 312 "inform7/Chapter 15/Kind Checking.w"
if ((to == NULL) && (from == NULL)) return ALWAYS_MATCH;
if ((to == NULL) || (from == NULL)) return NEVER_MATCH;
}
#line 288 "inform7/Chapter 15/Kind Checking.w"
;
{
#line 318 "inform7/Chapter 15/Kind Checking.w"
inference_subject *from_subj = Kinds__as_subject(from);
inference_subject *to_subj = Kinds__as_subject(to);
if ((World__Subjects__is_within(from_subj, Kinds__as_subject(K_object))) &&
(World__Subjects__is_within(to_subj, Kinds__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 (World__Subjects__is_strictly_within(from_subj, to_subj)) return ALWAYS_MATCH;
if (World__Subjects__is_strictly_within(to_subj, from_subj)) return SOMETIMES_MATCH;
return NEVER_MATCH;
}
}
#line 289 "inform7/Chapter 15/Kind Checking.w"
;
{
#line 334 "inform7/Chapter 15/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 = test_kind_relation(from->kc_args[i], to->kc_args[i], comp);
else
this_o = 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 290 "inform7/Chapter 15/Kind Checking.w"
;
}
#line 436 "inform7/Chapter 15/Kind Checking.w"
void Kinds__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");
}
#line 450 "inform7/Chapter 15/Kind Checking.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 461 "inform7/Chapter 15/Kind Checking.w"
void Kinds__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__lt(sub, K_object) == FALSE) return;
if (Config__Plugins__Call__set_subkind_notify(sub, super)) return;
kind *existing = Kinds__super(sub);
switch (Kinds__compatible(existing, super)) {
case NEVER_MATCH:
LOG("Tried to make $u a kind of $u\n", sub, super);
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, Kinds__get_superkind_set_at(sub));
Problems__quote_kind(3, super);
Problems__quote_kind(4, existing);
Problems__handmade_problem(_P_(C15KindUnalterable));
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 (World__Subjects__is_within(Kinds__as_subject(super), Kinds__as_subject(sub))) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, Kinds__get_superkind_set_at(super));
Problems__quote_kind(3, super);
Problems__quote_kind(4, existing);
Problems__handmade_problem(_P_(C15KindsCircular));
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;
}
World__Subjects__falls_within(Kinds__as_subject(sub), Kinds__as_subject(super));
Kinds__set_superkind_set_at(sub, current_sentence);
LOGIF(KIND_CHANGES, "Making $u a subkind of $u\n", sub, super);
}
}
#line 508 "inform7/Chapter 15/Kind Checking.w"
void Kinds__log_poset(int n) {
switch (n) {
case 1:
{
#line 522 "inform7/Chapter 15/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__le(A, B)) && (Kinds__eq(A, B) == FALSE)) {
if (c++ == 0) LOG("$u <= ", A); else LOG(", ");
LOG("$u", B);
}
}
if (c > 0) LOG("\n");
}
}
#line 510 "inform7/Chapter 15/Kind Checking.w"
; break;
case 2:
{
#line 538 "inform7/Chapter 15/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__compatible(A, B) == ALWAYS_MATCH) &&
(Kinds__le(A, B) == FALSE) &&
(Kinds__eq(A, K_value) == FALSE)) {
if (c++ == 0) LOG("$u --> ", A); else LOG(", ");
LOG("$u", B);
}
}
if (c > 0) LOG("\n");
}
}
#line 511 "inform7/Chapter 15/Kind Checking.w"
; break;
case 3:
{
#line 556 "inform7/Chapter 15/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__super(B))
LOG("$u -> ", B);
LOG("\n");
}
}
#line 512 "inform7/Chapter 15/Kind Checking.w"
; break;
case 4:
{
#line 567 "inform7/Chapter 15/Kind Checking.w"
LOG("Looking for partially ordered set violations.\n");
kind *A, *B, *C;
LOOP_OVER_BASE_KINDS(A)
if (Kinds__le(A, A) == FALSE)
LOG("Reflexivity violated: $u\n", A);
LOOP_OVER_BASE_KINDS(A)
LOOP_OVER_BASE_KINDS(B)
if ((Kinds__le(A, B)) && (Kinds__le(B, A)) && (Kinds__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__le(A, B)) && (Kinds__le(B, C)) && (Kinds__le(A, C) == FALSE))
LOG("Transitivity violated: $u, $u, $u\n", A, B, C);
}
#line 513 "inform7/Chapter 15/Kind Checking.w"
; break;
case 5:
{
#line 585 "inform7/Chapter 15/Kind Checking.w"
LOG("Looking for maximum violations.\n");
kind *A, *B;
LOOP_OVER_BASE_KINDS(A)
LOOP_OVER_BASE_KINDS(B)
if (Kinds__eq(Kinds__max(A, B), Kinds__max(B, A)) == FALSE)
LOG("Fail symmetry: max($u, $u) = $u, but max($u, $u) = $u\n",
A, B, Kinds__max(A, B), B, A, Kinds__max(B, A));
LOOP_OVER_BASE_KINDS(A)
LOOP_OVER_BASE_KINDS(B)
if (Kinds__le(A, Kinds__max(A, B)) == FALSE)
LOG("Fail maximality(A): max($u, $u) = $u\n", A, B, Kinds__max(A, B));
LOOP_OVER_BASE_KINDS(A)
LOOP_OVER_BASE_KINDS(B)
if (Kinds__le(B, Kinds__max(A, B)) == FALSE)
LOG("Fail maximality(B): max($u, $u) = $u\n", A, B, Kinds__max(A, B));
LOOP_OVER_BASE_KINDS(A)
if (Kinds__eq(Kinds__max(A, A), A) == FALSE)
LOG("Fail: max($u, $u) = $u\n",
A, A, Kinds__max(A, A));
}
#line 514 "inform7/Chapter 15/Kind Checking.w"
; break;
case 6:
{
#line 610 "inform7/Chapter 15/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__le(tests[i], tests[j])) LOG("$u <= $u\n", tests[i], tests[j]);
if (Kinds__le(tests[j], tests[i])) LOG("$u <= $u\n", tests[j], tests[i]);
kind *M = Kinds__max(tests[i], tests[j]);
if (Kinds__eq(M, K_value) == FALSE) LOG("max($u, $u) = $u\n", tests[i], tests[j], M);
}
}
#line 515 "inform7/Chapter 15/Kind Checking.w"
; break;
}
}
#line 156 "inform7/Chapter 15/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 184 "inform7/Chapter 15/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->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 {
Formats__Inform6__compose_identifier(con->dt_I6_identifier,
'T', (con->allocation_id)+1, -1, -1);
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 162 "inform7/Chapter 15/Kind Constructors.w"
else
{
#line 290 "inform7/Chapter 15/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 163 "inform7/Chapter 15/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 =
World__Subjects__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 15/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;
}
void Kinds__Constructors__get_name(kind_constructor *con, int *w1, int *w2, int plural_form) {
*w1 = -1; *w2 = -1;
if (con->dt_tag) {
nametag *nt = con->dt_tag;
if (nt) Data__Nametags__get_name(nt, w1, w2, plural_form);
}
}
void Kinds__Constructors__get_name_in_play(kind_constructor *con, int *w1, int *w2, int plural_form) {
*w1 = -1; *w2 = -1;
if (con->dt_tag) {
nametag *nt = con->dt_tag;
if (nt) Data__Nametags__get_name_in_play(nt, w1, w2, plural_form);
}
}
nametag *Kinds__Constructors__get_nametag(kind_constructor *con) {
if (con == NULL) return NULL;
return con->dt_tag;
}
#line 338 "inform7/Chapter 15/Kind Constructors.w"
void Kinds__Constructors__compile_I6_constants(OUTPUT_STREAM) {
WRITE("Constant UNKNOWN_TY = %d;\n", UNKNOWN);
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 358 "inform7/Chapter 15/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 384 "inform7/Chapter 15/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 393 "inform7/Chapter 15/Kind Constructors.w"
void Kinds__Constructors__mark_as_linguistic(kind_constructor *con) {
con->linguistic = TRUE;
}
#line 400 "inform7/Chapter 15/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 424 "inform7/Chapter 15/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 UNKNOWN;
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 465 "inform7/Chapter 15/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 485 "inform7/Chapter 15/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 504 "inform7/Chapter 15/Kind Constructors.w"
void Kinds__equate_latest(kind *K) {
if (latest_base_kind_of_value == NULL) internal_error("nothing to equate");
LOGIF(KIND_CREATIONS, "Making $u store as $u\n", latest_base_kind_of_value, K);
kind_constructor *con = Kinds__get_construct(latest_base_kind_of_value);
kind_constructor *stid = Kinds__get_construct(K);
if (con == NULL) internal_error("null con");
if (stid == NULL) internal_error("null stid");
con->is_incompletely_defined = FALSE;
con->constant_compilation_method = stid->constant_compilation_method;
strcpy(con->comparison_routine, stid->comparison_routine);
con->can_exchange = stid->can_exchange;
con->index_priority = stid->index_priority;
con->indexed_grey_if_empty = stid->indexed_grey_if_empty;
con->multiple_block = stid->multiple_block;
con->heap_size_estimate = stid->heap_size_estimate;
con->can_coincide_with_property = FALSE;
con->dim_rules = stid->dim_rules;
con->dimensional_form = stid->dimensional_form;
con->dimensional_form_fixed = stid->dimensional_form_fixed;
con->first_instance_rule = stid->first_instance_rule;
strcpy(con->dt_I6_identifier, stid->dt_I6_identifier);
con->stored_as = K;
}
#line 250 "inform7/Chapter 15/Kind Interpreter.w"
void Kinds__Interpreter__start(void) {
initialise_kind_text_archiver();
}
#line 266 "inform7/Chapter 15/Kind Interpreter.w"
kind_constructor *constructor_described = NULL;
int total_kind_command_lengths = 0;
void Kinds__Interpreter__despatch_kind_command(char *command) {
{
#line 295 "inform7/Chapter 15/Kind Interpreter.w"
total_kind_command_lengths += Platform__strlen(command) + 1;
if (total_kind_command_lengths >= MAX_KIND_COMMAND_FILE_LENGTH)
kind_command_error(command, "too great an extent of kind commands");
if (Platform__strlen(command) >= MAX_KIND_COMMAND_LENGTH)
kind_command_error(command, "kind command too long");
}
#line 270 "inform7/Chapter 15/Kind Interpreter.w"
;
if (recording_a_kind_template()) {
if (strcmp(command, "*END") == 0) end_kind_template();
else record_into_kind_template(command);
return;
}
if (command[Platform__strlen(command)-1] == ':') {
if (recording_a_kind_macro()) end_kind_macro();
command[Platform__strlen(command)-1] = 0; /* remove the terminal colon */
{
#line 304 "inform7/Chapter 15/Kind Interpreter.w"
if (command[0] == '#') begin_kind_macro(command);
else if (command[0] == '*') 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__Constructors__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))
Config__Plugins__Call__new_base_kind_notify(
Kinds__base_construction(constructor_described), name, -1, -1);
}
}
#line 281 "inform7/Chapter 15/Kind Interpreter.w"
;
return;
}
single_kind_command stc = parse_kind_command(command);
if (recording_a_kind_macro()) record_into_kind_macro(stc);
else if (constructor_described) apply_kind_command(stc, constructor_described);
else internal_error("kind command describes unspecified kind");
}
#line 326 "inform7/Chapter 15/Kind Interpreter.w"
single_kind_command parse_kind_command(char *command) {
char *argument = NULL;
single_kind_command stc;
{
#line 365 "inform7/Chapter 15/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) kind_command_error(command, "kind command without argument");
}
#line 330 "inform7/Chapter 15/Kind Interpreter.w"
;
{
#line 351 "inform7/Chapter 15/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 = Text__Words__lit_0();
stc.constructor_argument[0] = 0;
stc.macro_argument = NULL;
stc.template_argument = NULL;
}
#line 332 "inform7/Chapter 15/Kind Interpreter.w"
;
{
#line 382 "inform7/Chapter 15/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) kind_command_error(command, "no such kind command");
}
#line 333 "inform7/Chapter 15/Kind Interpreter.w"
;
switch(stc.which_kind_command->operand_type) {
case BOOLEAN_KCA:
{
#line 392 "inform7/Chapter 15/Kind Interpreter.w"
if (strcmp(argument, "yes") == 0) stc.boolean_argument = TRUE;
else if (strcmp(argument, "no") == 0) stc.boolean_argument = FALSE;
else kind_command_error(command, "boolean kind command takes yes/no argument");
}
#line 336 "inform7/Chapter 15/Kind Interpreter.w"
; break;
case CCM_KCA:
{
#line 399 "inform7/Chapter 15/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 kind_command_error(command, "kind command with unknown constant-compilation-method");
}
#line 337 "inform7/Chapter 15/Kind Interpreter.w"
; break;
case CONSTRUCTOR_KCA:
{
#line 442 "inform7/Chapter 15/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 = archive_kind_text(argument+i+3);
break;
}
Extensions__IDs__truncated_strcpy(stc.constructor_argument, argument, 31);
}
#line 338 "inform7/Chapter 15/Kind Interpreter.w"
; break;
case MACRO_KCA:
{
#line 461 "inform7/Chapter 15/Kind Interpreter.w"
stc.macro_argument = Kinds__Interpreter__parse_kind_macro_name(argument);
if (stc.macro_argument == NULL)
kind_command_error(command, "unknown template name in kind command");
}
#line 339 "inform7/Chapter 15/Kind Interpreter.w"
; break;
case NUMERIC_KCA:
{
#line 437 "inform7/Chapter 15/Kind Interpreter.w"
stc.numeric_argument = atoi(argument);
}
#line 340 "inform7/Chapter 15/Kind Interpreter.w"
; break;
case TEMPLATE_KCA:
{
#line 454 "inform7/Chapter 15/Kind Interpreter.w"
stc.template_argument = parse_kind_template_name(argument);
if (stc.template_argument == NULL)
kind_command_error(command, "unknown template name in kind command");
}
#line 341 "inform7/Chapter 15/Kind Interpreter.w"
; break;
case TEXT_KCA:
{
#line 408 "inform7/Chapter 15/Kind Interpreter.w"
stc.textual_argument = archive_kind_text(argument);
}
#line 342 "inform7/Chapter 15/Kind Interpreter.w"
; break;
case VOCABULARY_KCA:
{
#line 413 "inform7/Chapter 15/Kind Interpreter.w"
stc.vocabulary_argument = Text__Words__lit_0();
argument = 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 = Text__Words__join(
stc.vocabulary_argument, Text__Words__lit_1(
Text__Vocabulary__entry_for_text(latest_word)));
nw++;
latest_word = argument+i;
if (nw >= 30) {
kind_command_error(command, "too many words in kind command");
break;
}
}
stc.vocabulary_argument = Text__Words__join(
stc.vocabulary_argument, Text__Words__lit_1(
Text__Vocabulary__entry_for_text(latest_word)));
}
#line 343 "inform7/Chapter 15/Kind Interpreter.w"
; break;
}
return stc;
}
#line 504 "inform7/Chapter 15/Kind Interpreter.w"
kind_template_definition *new_kind_template(char *name) {
kind_template_definition *ttd = CREATE(kind_template_definition);
ttd->template_name = archive_kind_text(name);
return ttd;
}
kind_template_definition *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 522 "inform7/Chapter 15/Kind Interpreter.w"
kind_template_definition *current_kind_template = NULL; /* the one now being recorded */
int recording_a_kind_template(void) {
if (current_kind_template) return TRUE;
return FALSE;
}
void begin_kind_template(char *name) {
if (current_kind_template) internal_error("first stt still recording");
if (parse_kind_template_name(name))
internal_error("duplicate definition of source text template");
current_kind_template = new_kind_template(name);
current_kind_template->template_text = begin_recording_kind_text();
}
void record_into_kind_template(char *line) {
record_kind_text(line);
}
void end_kind_template(void) {
if (current_kind_template == NULL) internal_error("no stt currently recording");
end_recording_kind_text();
current_kind_template = NULL;
}
#line 553 "inform7/Chapter 15/Kind Interpreter.w"
void 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 562 "inform7/Chapter 15/Kind Interpreter.w"
void Kinds__Interpreter__include_templates_for_kinds(void) {
kind_template_obligation *tto;
LOOP_OVER(tto, kind_template_obligation)
transcribe_kind_template(tto->remembered_template, tto->remembered_constructor);
}
void 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[MAX_KIND_COMMAND_LENGTH], terminator = 0;
if ((p[i] == '\n') || (p[i] == ' ')) { i++; continue; }
{
#line 595 "inform7/Chapter 15/Kind Interpreter.w"
int j=0;
while ((p[i] != 0) && (p[i] != '\n')) {
if (p[i] == '<') {
char template_wildcard_buffer[MAX_KIND_COMMAND_LENGTH];
int k=0;
i++;
while ((p[i] != 0) && (p[i] != '\n') && (p[i] != '>'))
template_wildcard_buffer[k++] = p[i++];
template_wildcard_buffer[k++] = 0;
i++;
{
#line 617 "inform7/Chapter 15/Kind Interpreter.w"
if (strcmp(template_wildcard_buffer, "kind") == 0)
{
#line 633 "inform7/Chapter 15/Kind Interpreter.w"
transcribe_constructor_name(template_line_buffer+j, con, FALSE);
}
#line 618 "inform7/Chapter 15/Kind Interpreter.w"
else if (strcmp(template_wildcard_buffer, "lower-case-kind") == 0)
{
#line 638 "inform7/Chapter 15/Kind Interpreter.w"
transcribe_constructor_name(template_line_buffer+j, con, TRUE);
}
#line 620 "inform7/Chapter 15/Kind Interpreter.w"
else if (strcmp(template_wildcard_buffer, "kind-weak-ID") == 0)
{
#line 643 "inform7/Chapter 15/Kind Interpreter.w"
sprintf(template_line_buffer+j, "%d", con->weak_kind_ID);
}
#line 622 "inform7/Chapter 15/Kind Interpreter.w"
else if (strcmp(template_wildcard_buffer, "printing-routine") == 0)
{
#line 648 "inform7/Chapter 15/Kind Interpreter.w"
sprintf(template_line_buffer+j, "%s", con->dt_I6_identifier);
}
#line 624 "inform7/Chapter 15/Kind Interpreter.w"
else if (strcmp(template_wildcard_buffer, "comparison-routine") == 0)
{
#line 653 "inform7/Chapter 15/Kind Interpreter.w"
sprintf(template_line_buffer+j, "%s", con->comparison_routine);
}
#line 626 "inform7/Chapter 15/Kind Interpreter.w"
else internal_error("no such source text template wildcard");
j = Platform__strlen(template_line_buffer);
}
#line 605 "inform7/Chapter 15/Kind Interpreter.w"
;
} else template_line_buffer[j++] = p[i++];
}
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 575 "inform7/Chapter 15/Kind Interpreter.w"
;
if (template_line_buffer[0]) {
int x1 = lexer_wordcount, x2;
Text__feed_into_lexer(template_line_buffer, FALSE, NULL);
x2 = lexer_wordcount-1;
if (terminator != 0) Parser__Sentences__make_node(x1, x2, terminator, NULL);
}
}
Parser__Sentences__register_recently_lexed_phrases();
}
#line 658 "inform7/Chapter 15/Kind Interpreter.w"
void transcribe_constructor_name(char *buffer, kind_constructor *con, int lower_case) {
buffer[0] = 0;
int w1 = -1, w2 = -1;
if (con->dt_tag) Kinds__Constructors__get_name(con, &w1, &w2, FALSE);
if (w1 >= 0) {
if (Kinds__Constructors__arity(con) > 0) {
int full_length = w2 - w1 + 1;
int i;
for (i=0; i<full_length; i++) {
if (i > 0) strcpy(buffer+Platform__strlen(buffer), " ");
vocabulary_entry *ve = Text__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), Text__Vocabulary__get_exemplar(ve, FALSE));
}
} else {
if (lower_case) Text__print_raw_text_to_string(w1, w2, buffer);
else Text__print_text_to_string(w1, w2, buffer);
}
}
}
#line 685 "inform7/Chapter 15/Kind Interpreter.w"
kind_macro_definition *current_kind_macro = NULL; /* the one now being recorded */
kind_macro_definition *new_kind_macro(char *name) {
kind_macro_definition *tmd = CREATE(kind_macro_definition);
tmd->kind_macro_line_count = 0;
tmd->kind_macro_name = 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 704 "inform7/Chapter 15/Kind Interpreter.w"
int recording_a_kind_macro(void) {
if (current_kind_macro) return TRUE;
return FALSE;
}
void begin_kind_macro(char *name) {
if (Kinds__Interpreter__parse_kind_macro_name(name))
internal_error("duplicate definition of kind command macro");
current_kind_macro = new_kind_macro(name);
}
void 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 end_kind_macro(void) {
if (current_kind_macro == NULL) internal_error("ended kind macro outside one");
current_kind_macro = NULL;
}
#line 732 "inform7/Chapter 15/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++)
apply_kind_command(macro->kind_macro_line[i], con);
}
#line 747 "inform7/Chapter 15/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 initialise_kind_text_archiver(void) {
archive_for_kind_text[0] = 0;
}
char *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 766 "inform7/Chapter 15/Kind Interpreter.w"
char *begin_recording_kind_text(void) {
top_of_afdtt[0] = 0;
afdtt_recording_mode = TRUE;
return top_of_afdtt;
}
void 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 end_recording_kind_text(void) {
top_of_afdtt = top_of_afdtt + Platform__strlen(top_of_afdtt) + 1;
afdtt_recording_mode = FALSE;
}
#line 785 "inform7/Chapter 15/Kind Interpreter.w"
void kind_command_error(char *command, char *error) {
LOG("Kind command error found at: %s\n", command);
internal_error(error);
}
#line 833 "inform7/Chapter 15/Kind Interpreter.w"
void 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 849 "inform7/Chapter 15/Kind Interpreter.w"
switch (tcc) {
case apply_template_KCC:
if (text_loaded_from_source) transcribe_kind_template(stc.template_argument, con);
else 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 837 "inform7/Chapter 15/Kind Interpreter.w"
;
{
#line 867 "inform7/Chapter 15/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 839 "inform7/Chapter 15/Kind Interpreter.w"
;
{
#line 899 "inform7/Chapter 15/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 840 "inform7/Chapter 15/Kind Interpreter.w"
;
{
#line 928 "inform7/Chapter 15/Kind Interpreter.w"
switch (tcc) {
case constructor_arity_KCC:
{
#line 989 "inform7/Chapter 15/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 930 "inform7/Chapter 15/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;
Text__Words__as_array(&(stc.vocabulary_argument), &array, &length);
if (length == 1) {
Text__Vocabulary__set_kind(array[0], Kinds__base_construction(con));
} else {
int i;
for (i=0; i<length; i++) {
Text__Vocabulary__set_flags(array[i], KIND_SLOW_MC);
Text__Languages__mark_vocabulary(array[i], k_kind_NTM);
}
if (con->group != PROPER_CONSTRUCTOR_GRP) {
vocabulary_entry *ve = Text__Words__hyphenated(&(stc.vocabulary_argument));
if (ve) Text__Vocabulary__set_kind(ve, Kinds__base_construction(con));
}
}
int i, rw1 = lexer_wordcount, rw2;
for (i=0; i<length; i++)
Text__feed_into_lexer(
Text__Vocabulary__get_exemplar(array[i], FALSE), FALSE, NULL);
rw2 = lexer_wordcount - 1;
if (tcc == singular_KCC) {
int ro = 0;
if (con->group != PROPER_CONSTRUCTOR_GRP) ro = REGISTER_SINGULAR_NTOPT + REGISTER_PLURAL_NTOPT;
nametag *nt = Data__Nametags__new(rw1, rw2,
STORE_POINTER_kind_constructor(con), KIND_PRIORITY,
PARSE_EXACTLY_NTOPT + ro, KIND_SLOW_MC, NULL, NEUTER_GENDER);
con->dt_tag = nt;
} else {
Data__Nametags__set_plural_name(con->dt_tag, rw1, rw2);
}
return;
}
case modifying_adjective_KCC:
internal_error("the modifying-adjective syntax has been withdrawn");
return;
}
}
#line 841 "inform7/Chapter 15/Kind Interpreter.w"
;
internal_error("unimplemented kind command");
}
#line 1019 "inform7/Chapter 15/Kind Interpreter.w"
void Kinds__Interpreter__batch_done(void) {
}
#line 11 "inform7/Chapter 15/Using Kinds.w"
void Kinds__get_name(kind *K, int *w1, int *w2, int plural_form) {
*w1 = -1; *w2 = -1;
if (K == NULL) return;
Kinds__Constructors__get_name(K->construct, w1, w2, plural_form);
}
void Kinds__get_name_in_play(kind *K, int *w1, int *w2, int plural_form) {
*w1 = -1; *w2 = -1;
if (K == NULL) return;
Kinds__Constructors__get_name_in_play(K->construct, w1, w2, plural_form);
}
nametag *Kinds__get_nametag(kind *K) {
if (K == NULL) return NULL;
return K->construct->dt_tag;
}
#line 33 "inform7/Chapter 15/Using Kinds.w"
int Kinds__is_kind_of_kind(kind *K) {
if (K == NULL) return FALSE;
if (K->construct->group == KIND_OF_KIND_GRP) return TRUE;
return FALSE;
}
#line 44 "inform7/Chapter 15/Using Kinds.w"
int Kinds__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__definite(K->kc_args[i]) == FALSE)
return FALSE;
return TRUE;
}
int Kinds__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__semidefinite(K->kc_args[i]) == FALSE)
return FALSE;
return TRUE;
}
int Kinds__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__involves_var(K->kc_args[i], v))
return TRUE;
return FALSE;
}
#line 86 "inform7/Chapter 15/Using Kinds.w"
int Kinds__is_built_in(kind *K) {
if (K == NULL) return FALSE;
if (K->construct->defined_in_source_text) return FALSE;
return TRUE;
}
parse_node *Kinds__get_creating_sentence(kind *K) {
if (K == NULL) return FALSE;
return K->construct->where_defined_in_source_text;
}
#line 105 "inform7/Chapter 15/Using Kinds.w"
int Kinds__is_uncertainly_defined(kind *K) {
if (K == NULL) return FALSE;
return K->construct->is_incompletely_defined;
}
#line 113 "inform7/Chapter 15/Using Kinds.w"
int Kinds__is_an_enumeration(kind *K) {
if (K == NULL) return FALSE;
return Kinds__Constructors__is_enumeration(K->construct);
}
#line 123 "inform7/Chapter 15/Using Kinds.w"
int Kinds__convert_to_unit(kind *K) {
if (K == NULL) return FALSE;
return Kinds__Constructors__convert_to_unit(K->construct);
}
#line 131 "inform7/Chapter 15/Using Kinds.w"
void Kinds__convert_to_enumeration(kind *K) {
if (K) Kinds__Constructors__convert_to_enumeration(K->construct);
}
#line 138 "inform7/Chapter 15/Using Kinds.w"
void Kinds__convert_to_real(kind *K) {
if (K) Kinds__Constructors__convert_to_real(K->construct);
}
#line 147 "inform7/Chapter 15/Using Kinds.w"
int Kinds__new_enumerated_value(kind *K) {
if (K == NULL) return 0;
Kinds__convert_to_enumeration(K);
return K->construct->next_free_value++;
}
#line 156 "inform7/Chapter 15/Using Kinds.w"
kind *Kinds__stored_as(kind *K) {
if (K == NULL) return NULL;
return K->construct->stored_as;
}
#line 167 "inform7/Chapter 15/Using Kinds.w"
void Kinds__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__get_superkind_set_at(kind *K) {
if (K == NULL) return NULL;
return K->construct->superkind_set_at;
}
#line 183 "inform7/Chapter 15/Using Kinds.w"
int Kinds__has_named_constant_values(kind *K) {
if (K == NULL) return FALSE;
if (K->construct->named_values_created_with_assertions) return TRUE;
return FALSE;
}
#line 195 "inform7/Chapter 15/Using Kinds.w"
int Kinds__get_constant_compilation_method(kind *K) {
if (K == NULL) return NONE_CCM;
return K->construct->constant_compilation_method;
}
#line 206 "inform7/Chapter 15/Using Kinds.w"
void Kinds__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 =
Semantics__Nouns__LiteralPatterns__list_add(
K->construct->ways_to_write_literals, lp,
Kinds__uses_floating_point(lp->kind_specified));
}
#line 217 "inform7/Chapter 15/Using Kinds.w"
literal_pattern *Kinds__list_of_literal_forms(kind *K) {
if (K == NULL) return NULL;
return K->construct->ways_to_write_literals;
}
#line 225 "inform7/Chapter 15/Using Kinds.w"
int Kinds__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 244 "inform7/Chapter 15/Using Kinds.w"
int Kinds__has_properties(kind *K) {
if (K == NULL) return FALSE;
if (Kinds__is_an_enumeration(K)) return TRUE;
if (Kinds__le(K, K_object)) return TRUE;
return FALSE;
}
#line 265 "inform7/Chapter 15/Using Kinds.w"
inference_subject *Kinds__as_subject(kind *K) {
if (K == NULL) return NULL;
return K->construct->dt_knowledge;
}
void Kinds__set_subject(kind *K, inference_subject *infs) {
if (K == NULL) return;
K->construct->dt_knowledge = infs;
}
#line 279 "inform7/Chapter 15/Using Kinds.w"
void Kinds__Subjects__get_name_text(inference_subject *from, int *w1, int *w2) {
kind *K = World__Subjects__as_kind(from);
Kinds__get_name(K, w1, w2, FALSE);
}
void Kinds__Subjects__complete_model(inference_subject *infs) { }
void Kinds__Subjects__check_model(inference_subject *infs) { }
void Kinds__Subjects__write_element_of_condition(inference_subject *infs, char *cond) {
kind *K = World__Subjects__as_kind(infs);
if (Kinds__lt(K, K_object))
sprintf(cond, "t_0 ofclass %s", Kinds__I6_classname(K));
else if (Kinds__eq(K, K_object))
sprintf(cond, "t_0");
}
#line 298 "inform7/Chapter 15/Using Kinds.w"
general_pointer Kinds__Subjects__new_permission_granted(inference_subject *from) {
return STORE_POINTER_property_of_value_storage(
Properties__Implementation__OfValues__get_storage());
}
#line 308 "inform7/Chapter 15/Using Kinds.w"
void Kinds__Subjects__make_adj_const_domain(inference_subject *infs,
instance *nc, property *prn) {
kind *K = World__Subjects__as_kind(infs);
Data__Instances__make_adj_const_domain(nc, prn, K, NULL);
}
#line 318 "inform7/Chapter 15/Using Kinds.w"
void Kinds__Subjects__compile(OUTPUT_STREAM, inference_subject *infs) {
kind *K = World__Subjects__as_nonobject_kind(infs);
Properties__Implementation__OfValues__compile_properties(OUT, K);
}
int Kinds__Subjects__compile_all(OUTPUT_STREAM) {
return FALSE;
}
#line 338 "inform7/Chapter 15/Using Kinds.w"
int Kinds__compile_default_value(OUTPUT_STREAM, kind *K,
int w1, int w2, char *storage_name) {
if (Kinds__eq(K, K_value))
{
#line 448 "inform7/Chapter 15/Using Kinds.w"
Problems__quote_words_as_source(1, w1, w2);
Problems__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 341 "inform7/Chapter 15/Using Kinds.w"
;
if (Kinds__definite(K) == FALSE)
{
#line 419 "inform7/Chapter 15/Using Kinds.w"
if (w1 >= 0) {
Problems__quote_words_as_source(1, w1, w2);
Problems__quote_kind(2, K);
Problems__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__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 343 "inform7/Chapter 15/Using Kinds.w"
;
if ((Kinds__get_construct(K) == CON_list_of) ||
(Kinds__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) {
STREAM *BC = Kinds__RunTime__begin_block_constant(OUT, K);
Kinds__RuntimeIDs__compile_default_value(BC, K);
STREAM_WRITE(BC, " 0");
Kinds__RunTime__end_block_constant(K);
} else if (Kinds__eq(K, K_stored_action)) {
STREAM *BC = Kinds__RunTime__begin_block_constant(OUT, K);
Kinds__RunTime__compile_block_value_header(BC, K_stored_action, FALSE, 6);
STREAM_WRITE(BC, "##Wait 0 0 selfobj false 0");
Kinds__RunTime__end_block_constant(K_stored_action);
} else if (Kinds__get_construct(K) == CON_relation) {
STREAM *BC = Kinds__RunTime__begin_block_constant(OUT, K);
Semantics__Relations__compile_blank_relation(BC, K);
Kinds__RunTime__end_block_constant(K);
} else {
Kinds__RuntimeIDs__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__RuntimeIDs__compile_default_value(OUT, K);
return TRUE;
}
char *dvot = get_default_value_of_kind(K);
if (dvot) {
if (dvot[0] == '/') {
STREAM *BC = Kinds__RunTime__begin_block_constant(OUT, K);
STREAM_WRITE(BC, "%s", dvot+1);
Kinds__RunTime__end_block_constant(K);
} else {
WRITE("%s", dvot);
}
return TRUE;
}
if (Kinds__lt(K, K_object))
{
#line 397 "inform7/Chapter 15/Using Kinds.w"
if (w1 < 0) {
Problems__quote_kind(2, K);
Problems__handmade_problem(_P_(C15EmptyKind));
Problems__issue_problem_segment(
"I am unable to find %2 to use here, because the world does not "
"contain %2.");
Problems__issue_problem_end();
} else {
Problems__quote_words_as_source(1, w1, w2);
Problems__quote_kind(2, K);
Problems__quote_text(3, storage_name);
Problems__handmade_problem(_P_(C15EmptyKind2));
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();
}
return NOT_APPLICABLE;
}
#line 389 "inform7/Chapter 15/Using Kinds.w"
;
return FALSE;
}
#line 466 "inform7/Chapter 15/Using Kinds.w"
char *get_default_value_of_kind(kind *K) {
if (K == NULL) return NULL;
if (K->construct->stored_as) K = K->construct->stored_as;
if (Kinds__eq(K, K_object)) return "nothing";
instance *I;
LOOP_OVER_INSTANCES(I, K)
return Data__Instances__identifier(I);
if (Kinds__lt(K, K_object)) {
if (existing_story_file) return "nothing"; /* see above */
return NULL;
}
if (Kinds__is_an_enumeration(K)) return NULL;
if (Kinds__eq(K, K_rulebook_outcome))
return Code__Rulebooks__get_default_value();
return K->construct->default_value;
}
#line 507 "inform7/Chapter 15/Using Kinds.w"
int Kinds__name_can_coincide_with_property(kind *K) {
if (K == NULL) return FALSE;
return K->construct->can_coincide_with_property;
}
property *Kinds__get_coinciding_property(kind *K) {
if (K == NULL) return NULL;
return K->construct->coinciding_property;
}
void Kinds__set_coinciding_property(kind *K, property *P) {
if (K == NULL) return;
K->construct->coinciding_property = P;
}
#line 528 "inform7/Chapter 15/Using Kinds.w"
int Kinds__uses_signed_comparisons(kind *K) {
if (K == NULL) return FALSE;
if (strcmp(K->construct->comparison_routine, "signed") == 0) return TRUE;
return FALSE;
}
char *Kinds__get_comparison_routine(kind *K) {
if (K == NULL) return "";
if (strcmp(K->construct->comparison_routine, "signed") == 0) return "";
return K->construct->comparison_routine;
}
#line 547 "inform7/Chapter 15/Using Kinds.w"
int Kinds__is_quasinumerical(kind *K) {
if (K == NULL) return FALSE;
return Kinds__Constructors__is_arithmetic(K->construct);
}
unit_sequence *Kinds__get_dimensional_form(kind *K) {
if (K == NULL) return NULL;
if (Kinds__is_quasinumerical(K) == FALSE) return NULL;
if (K->construct == CON_INTERMEDIATE) return K->intermediate_result;
return &(K->construct->dimensional_form);
}
int Kinds__test_if_derived(kind *K) {
if (K == NULL) return FALSE;
return K->construct->dimensional_form_fixed;
}
void Kinds__now_derived(kind *K) {
if (K == NULL) internal_error("can't derive null kind");
K->construct->dimensional_form_fixed = TRUE;
}
int Kinds__scale_factor(kind *K) {
if (K == NULL) return 1;
if (K->intermediate_result)
return Kinds__Dimensions__us_get_scaling_factor(K->intermediate_result);
return Semantics__Nouns__LiteralPatterns__scale_factor(K);
}
#line 580 "inform7/Chapter 15/Using Kinds.w"
dimensional_rules *Kinds__get_dim_rules(kind *K) {
if (K == NULL) return NULL;
return &(K->construct->dim_rules);
}
#line 588 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__get_name_in_template_code(kind *K) {
if (K == NULL) return "UNKNOWN";
return K->construct->name_in_template_code;
}
#line 597 "inform7/Chapter 15/Using Kinds.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 613 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__I6_classname(kind *K) {
if (Kinds__eq(K, K_object)) return "K0_kind";
nametag *nt = Kinds__get_nametag(K);
if (nt == NULL) return NULL;
return Data__Nametags__identifier(nt);
}
int Kinds__I6_classnumber(kind *K) {
nametag *nt = Kinds__get_nametag(K);
if (nt == NULL) return 0;
return Data__Nametags__range_number(nt);
}
#line 629 "inform7/Chapter 15/Using Kinds.w"
void Kinds__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 643 "inform7/Chapter 15/Using Kinds.w"
int Kinds__uses_pointer_values(kind *K) {
if (K == NULL) return FALSE;
return dt_uses_pointer_values(K->construct);
}
#line 651 "inform7/Chapter 15/Using Kinds.w"
int Kinds__get_small_block_size(kind *K) {
if (K == NULL) return 0;
return K->construct->small_block_size;
}
#line 660 "inform7/Chapter 15/Using Kinds.w"
int Kinds__get_heap_size_estimate(kind *K) {
if (K == NULL) return 0;
return K->construct->heap_size_estimate;
}
int dt_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 allow_word_as_pointer(kind_constructor *left, kind_constructor *right) {
if (dt_uses_pointer_values(left) == FALSE) return FALSE;
if (dt_uses_pointer_values(right) == TRUE) return FALSE;
if (Kinds__Constructors__compatible(right, left, TRUE)) return TRUE;
return FALSE;
}
#line 684 "inform7/Chapter 15/Using Kinds.w"
int Kinds__allow_word_as_pointer(kind *left, kind *right) {
if ((left == NULL) || (right == NULL)) return FALSE;
return allow_word_as_pointer(left->construct, right->construct);
}
#line 692 "inform7/Chapter 15/Using Kinds.w"
int Kinds__cast_possible(kind *from, kind *to) {
from = Kinds__weaken(from);
to = Kinds__weaken(to);
if ((to) && (from) && (to->construct != from->construct) &&
(Kinds__definite(to)) && (Kinds__definite(from)) &&
(Kinds__eq(from, K_object) == FALSE) &&
(Kinds__eq(to, K_object) == FALSE) &&
(to->construct != CON_property))
return TRUE;
return FALSE;
}
#line 708 "inform7/Chapter 15/Using Kinds.w"
int Kinds__cast_call(OUTPUT_STREAM, kind *from, kind *to) {
if (Kinds__cast_possible(from, to)) {
if (Kinds__get_name_in_template_code(to)[0] == 0)
internal_error("cast by call impossible");
WRITE("%s_to_%s(",
Kinds__get_name_in_template_code(from),
Kinds__get_name_in_template_code(to));
if (Kinds__uses_pointer_values(to)) {
Code__Frames__compile_allocation(OUT, to);
WRITE(",");
}
return TRUE;
}
return FALSE;
}
#line 727 "inform7/Chapter 15/Using Kinds.w"
specification *Kinds__cast_constant(specification *value, kind *to) {
kind *from = Specifications__evaluates_to(value);
if (Kinds__cast_possible(from, to)) {
if ((Kinds__eq(from, K_number)) && (Kinds__eq(to, K_real_number))) {
value = Specifications__copy(value);
Specifications__Values__coerce_NUMBER_to_REAL_NUMBER(value);
return value;
}
}
return value;
}
#line 763 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__interpret_test_equality(kind *left, kind *right) {
LOGIF(KIND_CHECKING, "Interpreting equality test of kinds $u, $u\n", left, right);
if ((Kinds__eq(left, K_truth_state)) || (Kinds__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 (dt_uses_pointer_values(L)) {
if (allow_word_as_pointer(L, R)) {
pointer_allocation *pall =
Code__Frames__add_allocation(Kinds__base_construction(L),
"*=-BlkValueCompare(*1, BlkValueCast(*##, *#2, *!2))==0");
return Code__Frames__pall_get_expanded_schema(pall);
}
}
char *cr = Kinds__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 804 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__interpret_store(int 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__uses_floating_point(left)) form = INCREASE_BY_REAL;
}
if (inc < 0) {
form = DECREASE_BY_WORD;
if (Kinds__uses_floating_point(left)) form = DECREASE_BY_REAL;
}
if (dt_uses_pointer_values(L)) {
if (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 Specifications__Storage__storage_class_schema(storage_class,
form, Kinds__eq(left, K_time));
}
#line 837 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__get_distinguisher(kind *K) {
if (K == NULL) return NULL;
return K->construct->distinguisher;
}
#line 848 "inform7/Chapter 15/Using Kinds.w"
int Kinds__compile_domain_possible(kind *K) {
if (K == NULL) return FALSE;
if (Kinds__le(K, K_object)) return TRUE;
if (Kinds__is_an_enumeration(K)) return TRUE;
if (K->construct->loop_domain_schema) return TRUE;
return FALSE;
}
#line 878 "inform7/Chapter 15/Using Kinds.w"
int Kinds__write_loop_schema(i6_schema *sch, kind *K, int use_ix) {
if (K == NULL) return FALSE;
if (Kinds__lt(K, K_object)) {
if (Plugins__Counting__optimise_loop(sch, K) == FALSE)
Code__Schemas__modify(sch, "objectloop (*1 ofclass %s)",
Kinds__I6_classname(K));
return TRUE;
}
if (Kinds__eq(K, K_object)) {
Code__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__is_an_enumeration(K)) {
Code__Schemas__modify(sch,
"for (*1=1: *1<=%d: *1++)", Kinds__get_highest_valid_value_as_integer(K));
return TRUE;
}
if (p == NULL) return FALSE;
if (use_ix)
{
#line 921 "inform7/Chapter 15/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 904 "inform7/Chapter 15/Using Kinds.w"
else strcpy(q, p);
Code__Schemas__modify(sch, "%s", q);
return TRUE;
}
#line 933 "inform7/Chapter 15/Using Kinds.w"
int Kinds__requires_blanks_bitmap(kind *K) {
if (K == NULL) return FALSE;
if (Kinds__le(K, K_object)) return FALSE;
if (Kinds__is_an_enumeration(K)) return FALSE;
return TRUE;
}
#line 944 "inform7/Chapter 15/Using Kinds.w"
int Kinds__can_exchange(kind *K) {
if (K == NULL) return FALSE;
return K->construct->can_exchange;
}
#line 954 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__get_name_of_printing_rule(kind *K) {
if (K == NULL) return "DecimalNumber";
return K->construct->dt_I6_identifier;
}
#line 965 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__get_name_of_printing_rule_ACTIONS(kind *K) {
if (K == NULL) return "DA_Name";
return K->construct->name_of_printing_rule_ACTIONS;
}
#line 979 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__get_explicit_I6_GPR(kind *K) {
if (K == NULL) internal_error("Kinds__get_explicit_I6_GPR on null kind");
if (Kinds__le(K, K_object)) internal_error("wrong way to handle object grammar");
return K->construct->explicit_i6_GPR;
}
#line 988 "inform7/Chapter 15/Using Kinds.w"
int Kinds__offers_I6_GPR(kind *K) {
if (K == NULL) return FALSE;
return K->construct->has_i6_GPR;
}
#line 997 "inform7/Chapter 15/Using Kinds.w"
int Kinds__request_I6_GPR(kind *K) {
if (K == NULL) return FALSE;
if (Kinds__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 1008 "inform7/Chapter 15/Using Kinds.w"
int Kinds__needs_I6_GPR(kind *K) {
if (K == NULL) return FALSE;
return K->construct->I6_GPR_needed;
}
#line 1023 "inform7/Chapter 15/Using Kinds.w"
void Kinds__set_parsing_grammar(kind *K, grammar_verb *gv) {
if (K == NULL) return;
if (Kinds__le(K, K_object)) internal_error("wrong way to handle object grammar");
K->construct->understand_as_values = gv;
}
grammar_verb *Kinds__get_parsing_grammar(kind *K) {
if (K == NULL) return NULL;
if (Kinds__le(K, K_object)) internal_error("wrong way to handle object grammar");
return K->construct->understand_as_values;
}
#line 1040 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__get_recognition_only_GPR(kind *K) {
if (K == NULL) return NULL;
return K->construct->recognition_only_GPR;
}
#line 1048 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__get_documentation_reference(kind *K) {
if (K == NULL) return NULL;
return K->construct->documentation_reference;
}
void Kinds__set_documentation_reference(kind *K, char *dr) {
if (K == NULL) return;
K->construct->documentation_reference = dr;
}
#line 1062 "inform7/Chapter 15/Using Kinds.w"
char *Kinds__get_index_default_value(kind *K) {
if (K == NULL) return NULL;
return K->construct->index_default_value;
}
char *Kinds__get_index_minimum_value(kind *K) {
if (K == NULL) return NULL;
return K->construct->index_minimum_value;
}
char *Kinds__get_index_maximum_value(kind *K) {
if (K == NULL) return NULL;
return K->construct->index_maximum_value;
}
#line 1081 "inform7/Chapter 15/Using Kinds.w"
char *get_kind_description(kind *K) {
if (K == NULL) return "something";
return K->construct->constructor_description;
}
int Kinds__get_index_priority(kind *K) {
if (K == NULL) return 0;
return K->construct->index_priority;
}
int Kinds__indexed_grey_if_empty(kind *K) {
if (K == NULL) return FALSE;
return K->construct->indexed_grey_if_empty;
}
#line 1102 "inform7/Chapter 15/Using Kinds.w"
void Kinds__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__get_specification_text(kind *K) {
if (K == NULL) internal_error("can't get specification of null kind");
return K->construct->specification_text;
}
#line 58 "inform7/Chapter 15/Describing Kinds.w"
int if_parsing_phrase_tokens_NTMR(int w1, int w2, int *X, void **XP) {
#line 59 "inform7/Chapter 15/Describing Kinds.w"
if (kind_parsing_mode != NORMAL_KIND_PARSING) return TRUE;
return FALSE;
}
#line 68 "inform7/Chapter 15/Describing Kinds.w"
int spec_phrase_token_type_NTMR(int w1, int w2, int *X, void **XP) {
#line 69 "inform7/Chapter 15/Describing Kinds.w"
int s = kind_parsing_mode;
kind_parsing_mode = PHRASE_TOKEN_KIND_PARSING;
int t = parse_nt_against_word_range(spec_descriptive_type_expression_NTM, w1, w2, NULL, NULL);
kind_parsing_mode = s;
if (t) { *X = most_recent_result; *XP = most_recent_result_p; }
return t;
}
#line 82 "inform7/Chapter 15/Describing Kinds.w"
int k_kind_for_template_NTMR(int w1, int w2, int *X, void **XP) {
#line 83 "inform7/Chapter 15/Describing Kinds.w"
int s = kind_parsing_mode;
kind_parsing_mode = PHRASE_TOKEN_KIND_PARSING;
int t = parse_nt_against_word_range(k_kind_NTM, w1, w2, NULL, NULL);
kind_parsing_mode = s;
if (t) { *XP = most_recent_result_p; return TRUE; }
return FALSE;
}
#line 95 "inform7/Chapter 15/Describing Kinds.w"
int spec_kind_as_name_token_NTMR(int w1, int w2, int *X, void **XP) {
#line 96 "inform7/Chapter 15/Describing Kinds.w"
int s = kind_parsing_mode;
kind_parsing_mode = PHRASE_TOKEN_KIND_PARSING;
int t = parse_nt_against_word_range(k_kind_as_name_token_NTM, w1, w2, NULL, NULL);
kind_parsing_mode = s;
if (t) {
specification *spec = Specifications__Values__new_generic_CONSTANT(most_recent_result_p);
spec->word_ref1 = w1; spec->word_ref2 = w2;
*XP = spec;
*X = TRUE;
return TRUE;
}
return FALSE;
}
#line 114 "inform7/Chapter 15/Describing Kinds.w"
int k_kind_as_name_token_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 120 "inform7/Chapter 15/Describing Kinds.w"
int k_kind_abbreviating_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 125 "inform7/Chapter 15/Describing Kinds.w"
#line 129 "inform7/Chapter 15/Describing Kinds.w"
int k_kind_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 136 "inform7/Chapter 15/Describing Kinds.w"
#line 140 "inform7/Chapter 15/Describing Kinds.w"
int k_kind_articled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 143 "inform7/Chapter 15/Describing Kinds.w"
#line 148 "inform7/Chapter 15/Describing Kinds.w"
int k_variable_definition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 151 "inform7/Chapter 15/Describing Kinds.w"
#line 159 "inform7/Chapter 15/Describing Kinds.w"
int k_base_kind_NTMR(int w1, int w2, int *X, void **XP) {
#line 160 "inform7/Chapter 15/Describing Kinds.w"
kind *K = NULL;
if (w1 < 0) return FALSE;
if (w1 == w2) {
K = Text__Vocabulary__get_kind(Text__word(w1));
}
if (K == NULL) {
if (parse_nt_against_word_range(definite_article_NTM, w1, w1, NULL, NULL)) return FALSE;
meaning_list *ml = Parser__SP__parse_excerpt(KIND_SLOW_MC, w1, w2);
if (ml) {
excerpt_meaning *em = Parser__SP__MeaningLists__meaning(ml);
K = Kinds__base_construction(
RETRIEVE_POINTER_kind_constructor(Semantics__Nouns__ExcerptMeanings__data(em)));
} else {
ml = Parser__SP__parse_excerpt(NAMETAG_MC, w1, w2);
if (ml) {
nametag *nt = Data__Nametags__disambiguate(ml, KIND_PRIORITY);
if (nt) K = Kinds__base_construction(
RETRIEVE_POINTER_kind_constructor(Data__Nametags__tag_holder(nt)));
}
}
}
if (K) { *XP = K; return TRUE; }
return FALSE;
}
#line 195 "inform7/Chapter 15/Describing Kinds.w"
int k_irregular_kind_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = 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 3: *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 4: *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 5: *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 6: *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 7: *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 8: *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 205 "inform7/Chapter 15/Describing Kinds.w"
#line 210 "inform7/Chapter 15/Describing Kinds.w"
int k_kind_construction_NTMR(int w1, int w2, int *X, void **XP) {
#line 211 "inform7/Chapter 15/Describing Kinds.w"
kind_constructor *con;
LOOP_OVER(con, kind_constructor)
if (Kinds__Constructors__arity(con) > 0) {
int x1 = w1, x2 = w2, y1 = -1, y2 = -1;
if (parse_constructor_name(con, &x1, &x2, &y1, &y2))
{
#line 232 "inform7/Chapter 15/Describing Kinds.w"
kind *KX = K_value, *KY = K_value;
{
#line 261 "inform7/Chapter 15/Describing Kinds.w"
if ((con == CON_rule) || (con == CON_rulebook)) {
KX = K_action_name; KY = K_nil;
}
}
#line 234 "inform7/Chapter 15/Describing Kinds.w"
;
if (x1 >= 0) {
int tupling = Kinds__Constructors__tupling(con, 0);
if ((tupling == 0) && (parse_nt_against_word_range(k_single_material_NTM, x1, x2, NULL, NULL))) KX = most_recent_result_p;
else if ((tupling == 1) && (parse_nt_against_word_range(k_optional_material_NTM, x1, x2, NULL, NULL))) KX = most_recent_result_p;
else if ((tupling >= 2) && (parse_nt_against_word_range(k_tupled_material_NTM, x1, x2, NULL, NULL))) KX = most_recent_result_p;
else KX = NULL;
}
if (y1 >= 0) {
int tupling = Kinds__Constructors__tupling(con, 1);
if ((tupling == 0) && (parse_nt_against_word_range(k_single_material_NTM, y1, y2, NULL, NULL))) KY = most_recent_result_p;
else if ((tupling == 1) && (parse_nt_against_word_range(k_optional_material_NTM, y1, y2, NULL, NULL))) KY = most_recent_result_p;
else if ((tupling >= 2) && (parse_nt_against_word_range(k_tupled_material_NTM, y1, y2, NULL, NULL))) KY = most_recent_result_p;
else KY = NULL;
}
{
#line 268 "inform7/Chapter 15/Describing Kinds.w"
if ((con == CON_relation) && (y1 < 0)) KY = KX;
}
#line 249 "inform7/Chapter 15/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 216 "inform7/Chapter 15/Describing Kinds.w"
;
}
return FALSE;
}
#line 274 "inform7/Chapter 15/Describing Kinds.w"
int k_single_material_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 278 "inform7/Chapter 15/Describing Kinds.w"
int k_optional_material_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 285 "inform7/Chapter 15/Describing Kinds.w"
int k_tupled_material_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 290 "inform7/Chapter 15/Describing Kinds.w"
int k_tuple_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 294 "inform7/Chapter 15/Describing Kinds.w"
#line 302 "inform7/Chapter 15/Describing Kinds.w"
int parse_constructor_name(kind_constructor *con, int *K1, int *K2, int *L1, int *L2) {
int w1 = *K1, w2 = *K2;
int p;
for (p=1; p<=2; p++) {
int k1 = -1, k2 = -1;
Kinds__Constructors__get_name(con, &k1, &k2, (p==1)?FALSE:TRUE);
if (k1 >= 0) {
int full_length = k2-k1+1;
*K1 = -1; *K2 = -1; *L1 = -1; *L2 = -1;
{
#line 326 "inform7/Chapter 15/Describing Kinds.w"
int base = 0, length = full_length;
int k;
for (k=0; k<full_length; k++)
if (Text__word(k1+k) == STROKE_V) {
length = k - base;
if (length > 0)
{
#line 340 "inform7/Chapter 15/Describing Kinds.w"
if ((w2-w1+1) >= length) {
int i, p, failed = FALSE;
for (i=0, p=w1; i<length; i++) {
vocabulary_entry *ve = Text__word(k1+base+i);
if ((ve == CAPITAL_K_V) || (ve == CAPITAL_L_V)) {
int from = p;
if (i == length-1) { p = w2+1; }
else {
int bl = 0;
while (p <= w2) {
vocabulary_entry *nw = Text__word(p);
if (nw == OPENBRACKET_V) bl++;
else if (nw == CLOSEBRACKET_V) bl--;
else if (bl == 0) {
if (nw == Text__word(k1+base+i+1)) break;
}
p++;
}
if (p > w2) { failed = TRUE; break; }
}
if (ve == CAPITAL_K_V) { *K1 = from; *K2 = p-1; }
else { *L1 = from; *L2 = p-1; }
} else {
if (ve != Text__word(p++)) { failed = TRUE; break; }
}
}
if (p != w2+1) failed = TRUE;
if (failed == FALSE) return TRUE;
}
}
#line 331 "inform7/Chapter 15/Describing Kinds.w"
;
base = k+1;
}
length = full_length - base;
if (length > 0)
{
#line 340 "inform7/Chapter 15/Describing Kinds.w"
if ((w2-w1+1) >= length) {
int i, p, failed = FALSE;
for (i=0, p=w1; i<length; i++) {
vocabulary_entry *ve = Text__word(k1+base+i);
if ((ve == CAPITAL_K_V) || (ve == CAPITAL_L_V)) {
int from = p;
if (i == length-1) { p = w2+1; }
else {
int bl = 0;
while (p <= w2) {
vocabulary_entry *nw = Text__word(p);
if (nw == OPENBRACKET_V) bl++;
else if (nw == CLOSEBRACKET_V) bl--;
else if (bl == 0) {
if (nw == Text__word(k1+base+i+1)) break;
}
p++;
}
if (p > w2) { failed = TRUE; break; }
}
if (ve == CAPITAL_K_V) { *K1 = from; *K2 = p-1; }
else { *L1 = from; *L2 = p-1; }
} else {
if (ve != Text__word(p++)) { failed = TRUE; break; }
}
}
if (p != w2+1) failed = TRUE;
if (failed == FALSE) return TRUE;
}
}
#line 335 "inform7/Chapter 15/Describing Kinds.w"
;
}
#line 311 "inform7/Chapter 15/Describing Kinds.w"
;
}
}
*K1 = -1; *K2 = -1; *L1 = -1; *L2 = -1;
return FALSE;
}
#line 376 "inform7/Chapter 15/Describing Kinds.w"
int k_kind_of_kind_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *XP = RP[1]; if (Kinds__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 378 "inform7/Chapter 15/Describing Kinds.w"
#line 384 "inform7/Chapter 15/Describing Kinds.w"
int Parser__SP__parse_kind_variable_text(vocabulary_entry *ve) {
if (ve == NULL) return 0;
return parse_kind_variable_name(Text__Vocabulary__get_exemplar(ve, TRUE), TRUE);
}
int 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 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 422 "inform7/Chapter 15/Describing Kinds.w"
int k_kind_variable_NTMR(int w1, int w2, int *X, void **XP) {
#line 423 "inform7/Chapter 15/Describing Kinds.w"
int k = parse_kind_variable_name(Text__word_raw_text(w1), FALSE);
if (k != 0) {
kind *K = Code__Frames__get_kind_variable(k);
if (K) { *X = k; *XP = K; return TRUE; }
}
return FALSE;
}
#line 436 "inform7/Chapter 15/Describing Kinds.w"
int k_formal_kind_variable_NTMR(int w1, int w2, int *X, void **XP) {
#line 437 "inform7/Chapter 15/Describing Kinds.w"
int k = parse_kind_variable_name(Text__word_raw_text(w1), FALSE);
if (k != 0) {
*X = k; *XP = Kinds__variable_construction(k, NULL); return TRUE;
}
return FALSE;
}
#line 447 "inform7/Chapter 15/Describing Kinds.w"
int k_formal_kind_variable_singular_NTMR(int w1, int w2, int *X, void **XP) {
#line 448 "inform7/Chapter 15/Describing Kinds.w"
int k = parse_kind_variable_name_singular(Text__word_raw_text(w1));
if (k != 0) {
*X = k; *XP = Kinds__variable_construction(k, NULL); return TRUE;
}
return FALSE;
}
#line 459 "inform7/Chapter 15/Describing Kinds.w"
int k_kind_variable_texts_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 486 "inform7/Chapter 15/Describing Kinds.w"
#line 495 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__log(kind *K) {
Kinds__Textual__write(dl, K);
}
#line 502 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__Textual__write(OUTPUT_STREAM, kind *K) {
stream_kind_r(OUT, K, FALSE, FALSE);
}
void Kinds__Textual__write_plural(OUTPUT_STREAM, kind *K) {
stream_kind_r(OUT, K, TRUE, FALSE);
}
#line 513 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__Textual__write_articled(OUTPUT_STREAM, kind *K) {
TEMPORARY_STREAM;
stream_kind_r(TEMP, K, FALSE, TRUE);
Text__Inflections__preface_by_article(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
#line 523 "inform7/Chapter 15/Describing Kinds.w"
void stream_kind_r(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 540 "inform7/Chapter 15/Describing Kinds.w"
kind_constructor *con = Kinds__get_construct(K);
if (con == CON_NIL) { WRITE("nothing<nil>"); return; }
if (con == CON_TUPLE_ENTRY) {
{
#line 555 "inform7/Chapter 15/Describing Kinds.w"
kind *head = NULL, *tail = NULL;
Kinds__binary_construction_material(K, &head, &tail);
stream_kind_r(OUT, head, FALSE, substituting);
if (Kinds__get_construct(tail) != CON_NIL) {
WRITE(", ");
stream_kind_r(OUT, tail, FALSE, substituting);
}
}
#line 542 "inform7/Chapter 15/Describing Kinds.w"
; return; }
if (con == CON_KIND_VARIABLE) {
{
#line 566 "inform7/Chapter 15/Describing Kinds.w"
int vn = Kinds__get_variable_number(K);
if ((substituting) && (vn > 0)) {
kind *subst = Code__Frames__get_kind_variable(vn);
if (subst) { stream_kind_r(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__eq(S, K_value) == FALSE)) {
WRITE(" ["); Kinds__Textual__write(OUT, S); WRITE("]"); }
}
#line 543 "inform7/Chapter 15/Describing Kinds.w"
; return; }
if (con == CON_INTERMEDIATE) {
if (OUT == dl)
LOG("$Q", Kinds__get_dimensional_form(K));
else
Kinds__Dimensions__index_unit_sequence(OUT, Kinds__get_dimensional_form(K), FALSE);
return;
}
}
#line 528 "inform7/Chapter 15/Describing Kinds.w"
;
if (con)
{
#line 587 "inform7/Chapter 15/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 605 "inform7/Chapter 15/Describing Kinds.w"
if ((con == CON_property) && (Kinds__eq(first_base, K_truth_state))) {
WRITE("either/or property");
return;
}
}
#line 592 "inform7/Chapter 15/Describing Kinds.w"
;
int k1 = -1, k2 = -1;
Kinds__get_name(K, &k1, &k2, plural_form);
int full_length = k2 - k1 + 1;
int from, to;
{
#line 613 "inform7/Chapter 15/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 642 "inform7/Chapter 15/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 (Text__word(k1+i) == CAPITAL_K_V) k_present = 1;
if (Text__word(k1+i) == CAPITAL_L_V) l_present = 1;
if (Text__word(k1+i) == STROKE_V)
{
#line 656 "inform7/Chapter 15/Describing Kinds.w"
choice_from[k_present][l_present] = from;
choice_to[k_present][l_present] = i-1;
from = -1;
}
#line 649 "inform7/Chapter 15/Describing Kinds.w"
;
}
{
#line 656 "inform7/Chapter 15/Describing Kinds.w"
choice_from[k_present][l_present] = from;
choice_to[k_present][l_present] = i-1;
from = -1;
}
#line 651 "inform7/Chapter 15/Describing Kinds.w"
;
}
#line 615 "inform7/Chapter 15/Describing Kinds.w"
;
k_present = 1; l_present = 1;
if ((con == CON_rule) || (con == CON_rulebook)) {
if (Kinds__eq(first_base, K_action_name)) k_present = 0;
} else {
if (Kinds__eq(first_base, K_nil)) k_present = 0;
}
if ((con == CON_property) && (Kinds__eq(first_base, K_value))) k_present = 0;
if ((con == CON_table_column) && (Kinds__eq(first_base, K_value))) k_present = 0;
if ((con == CON_relation) && (Kinds__eq(first_base, second_base))) l_present = 0;
if (Kinds__Constructors__arity(con) == 1) l_present = 0;
else if (Kinds__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))
internal_error("constructor form choice failed");
}
#line 597 "inform7/Chapter 15/Describing Kinds.w"
;
{
#line 663 "inform7/Chapter 15/Describing Kinds.w"
int i;
for (i=from; i<=to; i++) {
if (i > from) WRITE(" ");
if (Text__word(k1+i) == CAPITAL_K_V) desc_base(OUT, con, 0, first_base, substituting);
else if (Text__word(k1+i) == CAPITAL_L_V) desc_base(OUT, con, 1, second_base, substituting);
else WRITE(Text__Vocabulary__get_exemplar(Text__word(k1+i), FALSE));
}
}
#line 598 "inform7/Chapter 15/Describing Kinds.w"
;
}
#line 529 "inform7/Chapter 15/Describing Kinds.w"
else
{
#line 580 "inform7/Chapter 15/Describing Kinds.w"
int w1, w2;
Kinds__get_name(K, &w1, &w2, plural_form);
Text__print_text_to_stream(w1, w2, OUT);
}
#line 530 "inform7/Chapter 15/Describing Kinds.w"
;
}
#line 674 "inform7/Chapter 15/Describing Kinds.w"
void 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;
stream_kind_r(OUT, K, pluralised, substituting);
if (bracketed) WRITE(")");
}
#line 722 "inform7/Chapter 15/Describing Kinds.w"
int Kinds__RuntimeIDs__weak(kind *K) {
if (K == NULL) return UNKNOWN;
return Kinds__Constructors__get_weak_ID(Kinds__get_construct(K));
}
#line 731 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__RuntimeIDs__compile_weak(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__RuntimeIDs__weak(K));
}
#line 779 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__RuntimeIDs__compile_strong(OUTPUT_STREAM, kind *K) {
runtime_kind_structure *rks = get_rks(K);
if (rks) {
WRITE("%s", rks->rks_identifier);
} else {
Kinds__RuntimeIDs__compile_weak(OUT, K);
}
}
#line 800 "inform7/Chapter 15/Describing Kinds.w"
runtime_kind_structure *get_rks(kind *K) {
kind *divert = Kinds__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 835 "inform7/Chapter 15/Describing Kinds.w"
LOOP_OVER(rks, runtime_kind_structure)
if (Kinds__eq(K, rks->kind_described))
break;
if (rks == NULL)
{
#line 845 "inform7/Chapter 15/Describing 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;
Formats__Inform6__purify_identifier(p);
}
#line 838 "inform7/Chapter 15/Describing Kinds.w"
;
}
#line 808 "inform7/Chapter 15/Describing Kinds.w"
;
switch (arity) {
case 1: {
kind *k = Kinds__unary_construction_material(K);
get_rks(k);
break;
}
case 2: {
kind *k = NULL, *l = NULL;
Kinds__binary_construction_material(K, &k, &l);
get_rks(k);
get_rks(l);
break;
}
}
}
}
return rks;
}
#line 872 "inform7/Chapter 15/Describing Kinds.w"
int Kinds__RuntimeIDs__compile_default_value(OUTPUT_STREAM, kind *K) {
Kinds__RuntimeIDs__precompile_default_value(K);
runtime_kind_structure *rks = get_rks(K);
if (rks == NULL) return FALSE;
WRITE("Default_Value_%d", rks->allocation_id);
return TRUE;
}
int Kinds__RuntimeIDs__precompile_default_value(kind *K) {
runtime_kind_structure *rks = 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 900 "inform7/Chapter 15/Describing Kinds.w"
void Kinds__compile_runtime_id_structures(OUTPUT_STREAM) {
runtime_kind_structure *rks;
LOOP_OVER(rks, runtime_kind_structure) {
kind *K = rks->kind_described;
int id = rks->allocation_id;
{
#line 914 "inform7/Chapter 15/Describing Kinds.w"
WRITE("Array %s --> ! ", rks->rks_identifier);
Kinds__Textual__write(OUT, K);
WRITE("\n");
INDENT;
Kinds__RuntimeIDs__compile_weak(OUT, K); WRITE(" ");
{
#line 925 "inform7/Chapter 15/Describing 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 962 "inform7/Chapter 15/Describing 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__RuntimeIDs__compile_strong(OUT, term); WRITE(" ");
}
}
#line 930 "inform7/Chapter 15/Describing Kinds.w"
;
WRITE(" "); Kinds__RuntimeIDs__compile_strong(OUT, result);
} else if (Kinds__get_construct(K) == CON_combination) {
arity--;
kind *X = Kinds__unary_construction_material(K);
{
#line 962 "inform7/Chapter 15/Describing 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__RuntimeIDs__compile_strong(OUT, term); WRITE(" ");
}
}
#line 935 "inform7/Chapter 15/Describing Kinds.w"
;
} else {
{
#line 943 "inform7/Chapter 15/Describing Kinds.w"
WRITE("%d", arity);
switch (arity) {
case 1: {
kind *X = Kinds__unary_construction_material(K);
WRITE(" "); Kinds__RuntimeIDs__compile_strong(OUT, X);
break;
}
case 2: {
kind *X = NULL, *Y = NULL;
Kinds__binary_construction_material(K, &X, &Y);
WRITE(" "); Kinds__RuntimeIDs__compile_strong(OUT, X);
WRITE(" "); Kinds__RuntimeIDs__compile_strong(OUT, Y);
break;
}
}
}
#line 937 "inform7/Chapter 15/Describing Kinds.w"
;
}
}
#line 919 "inform7/Chapter 15/Describing Kinds.w"
;
OUTDENT; WRITE(";\n");
}
#line 905 "inform7/Chapter 15/Describing Kinds.w"
;
if (rks->make_default)
{
#line 978 "inform7/Chapter 15/Describing Kinds.w"
char identifier[32];
sprintf(identifier, "Default_Value_%d", id);
current_sentence = rks->default_requested_here;
if (Kinds__get_construct(K) == CON_phrase) {
Code__Phrases__Constants__compile_default_closure(OUT, identifier, K);
} else if (Kinds__get_construct(K) == CON_relation) {
Semantics__Relations__compile_default_relation(OUT, identifier, K);
} else if (Kinds__get_construct(K) == CON_list_of) {
Data__Lists__compile_default_list(OUT, identifier, K);
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__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 906 "inform7/Chapter 15/Describing Kinds.w"
;
}
{
#line 1000 "inform7/Chapter 15/Describing Kinds.w"
OUT = Code__Routines__begin(OUT, "DefaultValueFinder");
Code__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__RuntimeIDs__compile_strong(OUT, K);
WRITE(") return Default_Value_%d;\n", rks->allocation_id);
}
}
WRITE("return 0;\n");
OUT = Code__Routines__end(OUT);
}
#line 908 "inform7/Chapter 15/Describing Kinds.w"
;
}
#line 326 "inform7/Chapter 15/Dimensions.w"
int 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 343 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__dim_initialise(dimensional_rules *dimrs) {
dimrs->multiplications = NULL;
}
#line 350 "inform7/Chapter 15/Dimensions.w"
void record_multiplication_rule(kind *left, kind *right, kind *outcome) {
dimensional_rules *dimrs = Kinds__get_dim_rules(left);
dimensional_rule *dimr;
for (dimr = dimrs->multiplications; dimr; dimr = dimr->next)
if (dimr->right == right) {
Problems__sentence_problem(_P_(C15DimensionRedundant),
"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;
dimr_new->word_ref1 = -1; dimr_new->word_ref2 = -1;
if (current_sentence) {
dimr_new->word_ref1 = current_sentence->word_ref1;
dimr_new->word_ref2 = current_sentence->word_ref2;
}
dimr_new->next = dimrs->multiplications;
dimrs->multiplications = dimr_new;
}
#line 396 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__dim_set_multiplication(kind *left, kind *right,
kind *outcome) {
LOG("Requested $u x $u = $u\n", left, right, outcome);
if ((Kinds__is_proper_constructor(left)) ||
(Kinds__is_proper_constructor(right)) ||
(Kinds__is_proper_constructor(outcome))) {
Problems__sentence_problem(_P_(C15DimensionNotBaseKOV),
"multiplication rules can only involve simple kinds of value",
"rather than complicated ones such as lists of other values.");
return;
}
if ((Kinds__is_quasinumerical(left) == FALSE) ||
(Kinds__is_quasinumerical(right) == FALSE) ||
(Kinds__is_quasinumerical(outcome) == FALSE)) {
Problems__sentence_problem(_P_(C15NonDimensional),
"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;
}
record_multiplication_rule(left, right, outcome);
if ((Kinds__eq(left, outcome)) && (Kinds__eq(right, K_number))) return;
if ((Kinds__eq(right, outcome)) && (Kinds__eq(left, K_number))) return;
make_unit_derivation(left, right, outcome);
Kinds__Dimensions__log_unit_analysis();
}
#line 431 "inform7/Chapter 15/Dimensions.w"
int Kinds__Dimensions__arithmetic_op_is_unary(int op) {
switch (op) {
case CUBEROOT_OPERATION:
case ROOT_OPERATION:
case UNARY_MINUS_OPERATION:
return TRUE;
}
return FALSE;
}
#line 458 "inform7/Chapter 15/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 471 "inform7/Chapter 15/Dimensions.w"
int lcm(int m, int n) {
return (m/Kinds__Dimensions__gcd(m, n))*n;
}
#line 481 "inform7/Chapter 15/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 497 "inform7/Chapter 15/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__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 533 "inform7/Chapter 15/Dimensions.w"
void 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 558 "inform7/Chapter 15/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 543 "inform7/Chapter 15/Dimensions.w"
;
{
#line 565 "inform7/Chapter 15/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 544 "inform7/Chapter 15/Dimensions.w"
;
if (Kinds__eq(t1, t2)) {
if (t1 == NULL) break; /* both sequences have now run out */
{
#line 575 "inform7/Chapter 15/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 612 "inform7/Chapter 15/Dimensions.w"
Problems__sentence_problem(_P_(C15UnitSequenceOverflow),
"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 578 "inform7/Chapter 15/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 547 "inform7/Chapter 15/Dimensions.w"
;
} else {
{
#line 594 "inform7/Chapter 15/Dimensions.w"
if ((t2 == NULL) || ((t1 != NULL) && (kind_prior(t1, t2)))) {
if (result->no_unit_pairs == MAX_BASE_UNITS_IN_SEQUENCE)
{
#line 612 "inform7/Chapter 15/Dimensions.w"
Problems__sentence_problem(_P_(C15UnitSequenceOverflow),
"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 596 "inform7/Chapter 15/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) && (kind_prior(t2, t1)))) {
if (result->no_unit_pairs == MAX_BASE_UNITS_IN_SEQUENCE)
{
#line 612 "inform7/Chapter 15/Dimensions.w"
Problems__sentence_problem(_P_(C15UnitSequenceOverflow),
"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 602 "inform7/Chapter 15/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 549 "inform7/Chapter 15/Dimensions.w"
;
}
}
LOGIF(KIND_CREATIONS, "Multiplication: $Q * $Q = $Q\n", us1, us2, result);
}
#line 633 "inform7/Chapter 15/Dimensions.w"
int 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 653 "inform7/Chapter 15/Dimensions.w"
void 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__eq(existing->unit_pairs[i].fund_unit, fundamental)) {
p = existing->unit_pairs[i].power;
found = TRUE;
{
#line 669 "inform7/Chapter 15/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 660 "inform7/Chapter 15/Dimensions.w"
;
}
if (found)
{
#line 676 "inform7/Chapter 15/Dimensions.w"
unit_sequence result;
multiply_unit_sequences(existing, 1, derived, p, &result);
*existing = result;
}
#line 663 "inform7/Chapter 15/Dimensions.w"
;
}
#line 684 "inform7/Chapter 15/Dimensions.w"
int Kinds__Dimensions__us_get_scaling_factor(unit_sequence *us) {
if (us == NULL) return 1;
return us->scaling_factor;
}
#line 692 "inform7/Chapter 15/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 "); }
int w1, w2;
Kinds__get_name(fundamental, &w1, &w2, FALSE);
Text__print_text_to_stream(w1, w2, OUT);
switch (power) {
case 1: break;
case 2: WRITE(" squared"); break;
case 3: WRITE(" cubed"); break;
default: WRITE(" to the power %d", power); break;
}
}
}
}
#line 725 "inform7/Chapter 15/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 755 "inform7/Chapter 15/Dimensions.w"
void 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 771 "inform7/Chapter 15/Dimensions.w"
int i; kind *max = NULL;
for (i=0; i<3; i++)
if ((kind_prior(max, terms[i])) && (Kinds__test_if_derived(terms[i]) == FALSE)) {
newest_term = i; max = terms[i];
}
}
#line 759 "inform7/Chapter 15/Dimensions.w"
;
if (newest_term >= 0) {
unit_sequence *derivation = NULL;
{
#line 781 "inform7/Chapter 15/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__get_dimensional_form(terms[1]); sx = -1;
ky = Kinds__get_dimensional_form(terms[2]); sy = 1;
break;
case 1: /* here $R$ is newest and we derive $R = L^{-1}O$ */
kx = Kinds__get_dimensional_form(terms[0]); sx = -1;
ky = Kinds__get_dimensional_form(terms[2]); sy = 1;
break;
case 2: /* here $O$ is newest and we derive $O = LR$ */
kx = Kinds__get_dimensional_form(terms[0]); sx = 1;
ky = Kinds__get_dimensional_form(terms[1]); sy = 1;
break;
}
derivation = Kinds__get_dimensional_form(terms[newest_term]);
unit_sequence result;
multiply_unit_sequences(kx, sx, ky, sy, &result);
*derivation = result;
Kinds__now_derived(terms[newest_term]);
}
#line 762 "inform7/Chapter 15/Dimensions.w"
;
{
#line 808 "inform7/Chapter 15/Dimensions.w"
kind *R;
LOOP_OVER_BASE_KINDS(R)
if (Kinds__is_quasinumerical(R)) {
unit_sequence *existing = Kinds__get_dimensional_form(R);
dim_substitute(existing, terms[newest_term], derivation);
}
}
#line 763 "inform7/Chapter 15/Dimensions.w"
;
} else
{
#line 825 "inform7/Chapter 15/Dimensions.w"
unit_sequence product;
multiply_unit_sequences(
Kinds__get_dimensional_form(terms[0]), 1,
Kinds__get_dimensional_form(terms[1]), 1, &product);
if (Kinds__Dimensions__compare_unit_sequences(&product,
Kinds__get_dimensional_form(terms[2])) == FALSE)
Problems__sentence_problem(_P_(C15DimensionsInconsistent),
"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 765 "inform7/Chapter 15/Dimensions.w"
;
}
#line 842 "inform7/Chapter 15/Dimensions.w"
int Kinds__Dimensions__dimensionless(kind *K) {
if (K == NULL) return FALSE;
if (Kinds__eq(K, K_number)) return TRUE;
if (Kinds__eq(K, K_real_number)) return TRUE;
if (Kinds__is_quasinumerical(K) == FALSE) return FALSE;
unit_sequence *deriv = Kinds__get_dimensional_form(K);
if ((deriv) && (deriv->no_unit_pairs == 0)) return TRUE;
return FALSE;
}
#line 856 "inform7/Chapter 15/Dimensions.w"
void Kinds__Dimensions__index_dimensional_rules(void) {
INDEX("<p><hr><p>");
{
#line 866 "inform7/Chapter 15/Dimensions.w"
INDEX("<a name=calculator>");
Formats__HTML__begin_plain_html_table(ifl);
Formats__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).");
Formats__HTML__end_html_row(ifl);
Formats__HTML__end_html_table(ifl);
INDEX("<p>");
}
#line 858 "inform7/Chapter 15/Dimensions.w"
;
{
#line 881 "inform7/Chapter 15/Dimensions.w"
Formats__HTML__begin_plain_html_table(ifl);
Formats__HTML__first_html_column(ifl, 0);
INDEX("<b>kind of value</b>");
Formats__HTML__next_html_column(ifl, 0);
INDEX("<b>minimum</b>");
Formats__HTML__next_html_column(ifl, 0);
INDEX("<b>maximum</b>");
Formats__HTML__next_html_column(ifl, 0);
INDEX("<b>dimensions</b>");
Formats__HTML__end_html_row(ifl);
kind *R;
LOOP_OVER_BASE_KINDS(R)
if (Kinds__is_quasinumerical(R)) {
if (Kinds__is_intermediate(R)) continue;
Formats__HTML__first_html_column(ifl, 0);
Kinds__Index__index_kind(R, FALSE, FALSE);
Formats__HTML__next_html_column(ifl, 0);
{
#line 917 "inform7/Chapter 15/Dimensions.w"
if (Kinds__eq(R, K_number)) INDEX("1");
else {
char *p = Kinds__get_index_minimum_value(R);
if (p) INDEX("%s", p);
else Semantics__Nouns__LiteralPatterns__index_value(
Kinds__list_of_literal_forms(R), 1);
}
}
#line 900 "inform7/Chapter 15/Dimensions.w"
;
Formats__HTML__next_html_column(ifl, 0);
{
#line 928 "inform7/Chapter 15/Dimensions.w"
if (Kinds__eq(R, K_number)) {
if (Code__VirtualMachines__is_16_bit()) INDEX("32767");
else INDEX("2147483647");
} else {
char *p = Kinds__get_index_maximum_value(R);
if (p) INDEX("%s", p);
else {
if (Code__VirtualMachines__is_16_bit())
Semantics__Nouns__LiteralPatterns__index_value(
Kinds__list_of_literal_forms(R), 32767);
else
Semantics__Nouns__LiteralPatterns__index_value(
Kinds__list_of_literal_forms(R), 2147483647);
}
}
}
#line 902 "inform7/Chapter 15/Dimensions.w"
;
Formats__HTML__next_html_column(ifl, 0);
if (Kinds__Dimensions__dimensionless(R)) INDEX("<i>dimensionless</i>");
else {
unit_sequence *deriv = Kinds__get_dimensional_form(R);
Kinds__Dimensions__index_unit_sequence(ifl, deriv, TRUE);
}
Formats__HTML__end_html_row(ifl);
}
Formats__HTML__end_html_table(ifl); INDEX("<p>");
}
#line 859 "inform7/Chapter 15/Dimensions.w"
;
{
#line 949 "inform7/Chapter 15/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");
Formats__HTML__begin_plain_html_table(ifl);
}
Formats__HTML__first_html_column(ifl, 0);
if (wn >= 0) Index__link(wn);
Formats__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;");
Formats__HTML__next_html_column(ifl, 0);
Semantics__Nouns__LiteralPatterns__index_benchmark_value(L);
INDEX("<font color=\"#808080\"> x </font>");
Semantics__Nouns__LiteralPatterns__index_benchmark_value(R);
INDEX("<font color=\"#808080\"> = </font>");
Semantics__Nouns__LiteralPatterns__index_benchmark_value(O);
Formats__HTML__end_html_row(ifl);
}
if (NP > 0) { Formats__HTML__end_html_table(ifl); INDEX("<p>"); }
}
#line 860 "inform7/Chapter 15/Dimensions.w"
;
}
#line 979 "inform7/Chapter 15/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) &&
(kind_is_derived(R) == FALSE) &&
(Kinds__is_quasinumerical(R)))
{ if (c++ > 0) LOG(", "); LOG("$u", R); }
LOG("\nDerived units:\n");
LOOP_OVER_BASE_KINDS(R)
if ((kind_is_derived(R)) && (Kinds__is_intermediate(R) == FALSE)) {
unit_sequence *deriv = Kinds__get_dimensional_form(R);
LOG("$u = $Q\n", R, deriv);
}
}
int kind_is_derived(kind *K) {
if (Kinds__is_intermediate(K)) return TRUE;
if ((Kinds__is_quasinumerical(K)) &&
(Kinds__test_if_derived(K) == TRUE) &&
(Kinds__Dimensions__dimensionless(K) == FALSE)) return TRUE;
return FALSE;
}
#line 1040 "inform7/Chapter 15/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__scale_factor(kindx);
int k_Y = Kinds__scale_factor(kindy);
int k_O = Kinds__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 1057 "inform7/Chapter 15/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__scale_factor(kindx);
int k_Y = Kinds__scale_factor(kindy);
int k_O = Kinds__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 1071 "inform7/Chapter 15/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__scale_factor(kindx);
int k_O = Kinds__scale_factor(kindo);
if (power == 2)
{
#line 1096 "inform7/Chapter 15/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 1080 "inform7/Chapter 15/Dimensions.w"
else if (power == 3)
{
#line 1107 "inform7/Chapter 15/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 1081 "inform7/Chapter 15/Dimensions.w"
else internal_error("can only scale square and cube roots");
}
#line 1120 "inform7/Chapter 15/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__get_dimensional_form(K1);
unit_sequence *operand2 = Kinds__get_dimensional_form(K2);
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:
root_unit_sequence(operand1, 2, &result);
break;
case CUBEROOT_OPERATION:
root_unit_sequence(operand1, 3, &result);
break;
case TIMES_OPERATION:
multiply_unit_sequences(operand1, 1, operand2, 1, &result);
break;
case DIVIDE_OPERATION:
multiply_unit_sequences(operand1, 1, operand2, -1, &result);
break;
default: return NULL;
}
{
#line 1174 "inform7/Chapter 15/Dimensions.w"
if (Kinds__Dimensions__arithmetic_op_is_unary(op)) {
if (Kinds__Dimensions__dimensionless(K1)) return K1;
} else {
if ((Kinds__Dimensions__dimensionless(K1)) &&
(Kinds__Dimensions__dimensionless(K2))) {
if (Kinds__eq(K2, K_number)) return K1;
if (Kinds__eq(K1, K_number)) return K2;
if (Kinds__eq(K1, K2)) return K1;
}
}
}
#line 1157 "inform7/Chapter 15/Dimensions.w"
;
{
#line 1191 "inform7/Chapter 15/Dimensions.w"
kind *R;
LOOP_OVER_BASE_KINDS(R)
if (Kinds__Dimensions__compare_unit_sequences(&result,
Kinds__get_dimensional_form(R)))
return R;
}
#line 1158 "inform7/Chapter 15/Dimensions.w"
;
{
#line 1222 "inform7/Chapter 15/Dimensions.w"
result.scaling_factor = lcm(Kinds__scale_factor(K1), Kinds__scale_factor(K2));
return Kinds__intermediate_construction(&result);
}
#line 1159 "inform7/Chapter 15/Dimensions.w"
;
}
#line 1228 "inform7/Chapter 15/Dimensions.w"
void Kinds__perform_arithmetic(OUTPUT_STREAM, int op, equation *eqn,
specification *X, equation_node *EX, kind *KX,
specification *Y, equation_node *EY, kind *KY) {
int binary = TRUE;
if ((op == ROOT_OPERATION) || (op == CUBEROOT_OPERATION) || (op == UNARY_MINUS_OPERATION))
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__eq(KR, K_time)) reduce_modulo_1440 = TRUE;
}
{
#line 1271 "inform7/Chapter 15/Dimensions.w"
if (binary) {
if (Kinds__uses_floating_point(KX)) {
if (Kinds__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__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__uses_floating_point(KX)) {
use_fp = TRUE; promote_X = FALSE; promote_Y = FALSE;
} else {
use_fp = FALSE; promote_X = FALSE; promote_Y = FALSE;
}
}
}
#line 1239 "inform7/Chapter 15/Dimensions.w"
;
if (reduce_modulo_1440) WRITE("(NUMBER_TY_to_TIME_TY(");
switch (op) {
case EQUALS_OPERATION:
{
#line 1446 "inform7/Chapter 15/Dimensions.w"
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1446 "inform7/Chapter 15/Dimensions.w"
;
WRITE(" = ");
if (promote_Y) begin_flotation(OUT, KY);
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1449 "inform7/Chapter 15/Dimensions.w"
;
if (promote_Y) end_flotation(OUT, KY);
}
#line 1242 "inform7/Chapter 15/Dimensions.w"
; break;
case PLUS_OPERATION:
{
#line 1296 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Plus(");
if (promote_X) begin_flotation(OUT, KX);
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1299 "inform7/Chapter 15/Dimensions.w"
;
if (promote_X) end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) begin_flotation(OUT, KY);
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1303 "inform7/Chapter 15/Dimensions.w"
;
if (promote_Y) end_flotation(OUT, KY);
WRITE(")");
} else {
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1307 "inform7/Chapter 15/Dimensions.w"
;
WRITE(" + ");
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1309 "inform7/Chapter 15/Dimensions.w"
;
}
}
#line 1243 "inform7/Chapter 15/Dimensions.w"
; break;
case MINUS_OPERATION:
{
#line 1315 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Minus(");
if (promote_X) begin_flotation(OUT, KX);
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1318 "inform7/Chapter 15/Dimensions.w"
;
if (promote_X) end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) begin_flotation(OUT, KY);
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1322 "inform7/Chapter 15/Dimensions.w"
;
if (promote_Y) end_flotation(OUT, KY);
WRITE(")");
} else {
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1326 "inform7/Chapter 15/Dimensions.w"
;
WRITE(" - ");
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1328 "inform7/Chapter 15/Dimensions.w"
;
}
}
#line 1244 "inform7/Chapter 15/Dimensions.w"
; break;
case TIMES_OPERATION:
{
#line 1334 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Times(");
if (promote_X) begin_flotation(OUT, KX);
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1337 "inform7/Chapter 15/Dimensions.w"
;
if (promote_X) end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) begin_flotation(OUT, KY);
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1341 "inform7/Chapter 15/Dimensions.w"
;
if (promote_Y) end_flotation(OUT, KY);
WRITE(")");
} else {
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1345 "inform7/Chapter 15/Dimensions.w"
;
WRITE(" * ");
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1347 "inform7/Chapter 15/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_multiplication(OUT, KX, KY);
}
}
#line 1245 "inform7/Chapter 15/Dimensions.w"
; break;
case DIVIDE_OPERATION:
{
#line 1354 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Divide(");
if (promote_X) begin_flotation(OUT, KX);
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1357 "inform7/Chapter 15/Dimensions.w"
;
if (promote_X) end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) begin_flotation(OUT, KY);
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1361 "inform7/Chapter 15/Dimensions.w"
;
if (promote_Y) end_flotation(OUT, KY);
WRITE(")");
} else {
WRITE("IntegerDivide(");
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1366 "inform7/Chapter 15/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_division(OUT, KX, KY);
WRITE(", ");
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1369 "inform7/Chapter 15/Dimensions.w"
;
WRITE(")");
}
}
#line 1246 "inform7/Chapter 15/Dimensions.w"
; break;
case REMAINDER_OPERATION:
{
#line 1376 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Remainder(");
if (promote_X) begin_flotation(OUT, KX);
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1379 "inform7/Chapter 15/Dimensions.w"
;
if (promote_X) end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) begin_flotation(OUT, KY);
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1383 "inform7/Chapter 15/Dimensions.w"
;
if (promote_Y) end_flotation(OUT, KY);
WRITE(")");
} else {
WRITE("IntegerRemainder(");
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1388 "inform7/Chapter 15/Dimensions.w"
;
WRITE(", ");
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1390 "inform7/Chapter 15/Dimensions.w"
;
WRITE(")");
}
}
#line 1247 "inform7/Chapter 15/Dimensions.w"
; break;
case APPROXIMATION_OPERATION:
{
#line 1397 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Approximate(");
if (promote_X) begin_flotation(OUT, KX);
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1400 "inform7/Chapter 15/Dimensions.w"
;
if (promote_X) end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) begin_flotation(OUT, KY);
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1404 "inform7/Chapter 15/Dimensions.w"
;
if (promote_Y) end_flotation(OUT, KY);
WRITE(")");
} else {
WRITE("RoundOffTime(");
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1409 "inform7/Chapter 15/Dimensions.w"
;
WRITE(", ");
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1411 "inform7/Chapter 15/Dimensions.w"
;
WRITE(")");
}
}
#line 1248 "inform7/Chapter 15/Dimensions.w"
; break;
case ROOT_OPERATION:
{
#line 1418 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Root(");
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1420 "inform7/Chapter 15/Dimensions.w"
;
WRITE(")");
} else {
WRITE("SquareRoot(");
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1424 "inform7/Chapter 15/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_root(OUT, KX, 2);
WRITE(")");
}
}
#line 1249 "inform7/Chapter 15/Dimensions.w"
; break;
case CUBEROOT_OPERATION:
{
#line 1432 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Cube_Root(");
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1434 "inform7/Chapter 15/Dimensions.w"
;
WRITE(")");
} else {
WRITE("CubeRoot(");
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1438 "inform7/Chapter 15/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_root(OUT, KX, 3);
WRITE(")");
}
}
#line 1250 "inform7/Chapter 15/Dimensions.w"
; break;
case POWER_OPERATION:
{
#line 1470 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Pow(");
if (promote_X) begin_flotation(OUT, KX);
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1473 "inform7/Chapter 15/Dimensions.w"
;
if (promote_X) end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) begin_flotation(OUT, KY);
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1477 "inform7/Chapter 15/Dimensions.w"
;
if (promote_Y) end_flotation(OUT, KY);
WRITE(")");
} else {
int p = 0;
if (Y) p = Specifications__Values__get_literal_value(Y);
else p = Specifications__Values__get_literal_value(EY->leaf_constant);
if (p <= 0) enode_compilation_error(eqn, EY);
else {
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1486 "inform7/Chapter 15/Dimensions.w"
;
while (p > 1) {
WRITE(" * ");
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1488 "inform7/Chapter 15/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_multiplication(OUT, KX, KX);
p--;
}
}
}
}
#line 1251 "inform7/Chapter 15/Dimensions.w"
; break;
case UNARY_MINUS_OPERATION:
{
#line 1455 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Negate(");
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1457 "inform7/Chapter 15/Dimensions.w"
;
WRITE(")");
} else {
WRITE("-(");
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1461 "inform7/Chapter 15/Dimensions.w"
;
WRITE(")");
}
}
#line 1252 "inform7/Chapter 15/Dimensions.w"
; break;
case IMPLICIT_APPLICATION_OPERATION:
{
#line 1498 "inform7/Chapter 15/Dimensions.w"
if (use_fp) {
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1499 "inform7/Chapter 15/Dimensions.w"
;
WRITE("(");
if (promote_Y) begin_flotation(OUT, KY);
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1502 "inform7/Chapter 15/Dimensions.w"
;
if (promote_Y) end_flotation(OUT, KY);
WRITE(")");
} else {
{
#line 1515 "inform7/Chapter 15/Dimensions.w"
if (X) Specifications__compile_to_kind(OUT, X, KX); else enode_compile(OUT, eqn, EX);
}
#line 1506 "inform7/Chapter 15/Dimensions.w"
;
WRITE("(");
{
#line 1520 "inform7/Chapter 15/Dimensions.w"
if (Y) Specifications__compile_to_kind(OUT, Y, KY); else enode_compile(OUT, eqn, EY);
}
#line 1508 "inform7/Chapter 15/Dimensions.w"
;
WRITE(")");
}
}
#line 1253 "inform7/Chapter 15/Dimensions.w"
; break;
default:
Problems__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 1525 "inform7/Chapter 15/Dimensions.w"
void begin_flotation(OUTPUT_STREAM, kind *K) {
if (Kinds__scale_factor(K) != 1) WRITE("REAL_NUMBER_TY_Divide(");
WRITE("NUMBER_TY_to_REAL_NUMBER_TY");
WRITE("(");
}
void end_flotation(OUTPUT_STREAM, kind *K) {
WRITE(")");
if (Kinds__scale_factor(K) != 1)
WRITE(", NUMBER_TY_to_REAL_NUMBER_TY(%d))",
Kinds__scale_factor(K));
}
void begin_deflotation(OUTPUT_STREAM, kind *K) {
WRITE("REAL_NUMBER_TY_to_NUMBER_TY(");
if (Kinds__scale_factor(K) != 1) WRITE("REAL_NUMBER_TY_Times(");
}
void end_deflotation(OUTPUT_STREAM, kind *K) {
if (Kinds__scale_factor(K) != 1)
WRITE(", NUMBER_TY_to_REAL_NUMBER_TY(%d))",
Kinds__scale_factor(K));
WRITE(")");
}
#line 1553 "inform7/Chapter 15/Dimensions.w"
generalised_kind Kinds__Generalised__new(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;
}
kind *Kinds__Generalised__underlying(generalised_kind gK) {
return gK.valid_kind;
}
int Kinds__Generalised__uses_floating_point(generalised_kind gK) {
if (gK.promotion == 1) return TRUE;
if (Kinds__uses_floating_point(gK.valid_kind)) return TRUE;
return FALSE;
}
generalised_kind Kinds__Generalised__to_integer(generalised_kind gK) {
if (Kinds__Generalised__uses_floating_point(gK) == TRUE) {
if (gK.promotion == 1) gK.promotion = 0;
else {
kind *K = Kinds__to_integer(gK.valid_kind);
if (Kinds__uses_floating_point(K) == FALSE) gK.valid_kind = K;
else gK.promotion = -1;
}
}
if (Kinds__Generalised__uses_floating_point(gK) == TRUE)
internal_error("gK inconsistent");
return gK;
}
generalised_kind Kinds__Generalised__to_real(generalised_kind gK) {
if (Kinds__Generalised__uses_floating_point(gK) == FALSE) {
if (gK.promotion == -1) gK.promotion = 0;
else {
kind *K = Kinds__to_real(gK.valid_kind);
if (Kinds__uses_floating_point(K)) gK.valid_kind = K;
else gK.promotion = 1;
}
}
if (Kinds__Generalised__uses_floating_point(gK) == FALSE)
internal_error("gK inconsistent");
return gK;
}
int Kinds__uses_floating_point(kind *K) {
if (K == NULL) return FALSE;
return Kinds__Constructors__is_arithmetic_and_real(K->construct);
}
kind *Kinds__to_real(kind *K) {
if (Kinds__eq(K, K_number)) return K_real_number;
return K;
}
kind *Kinds__to_integer(kind *K) {
if (Kinds__eq(K, K_real_number)) return K_number;
return K;
}
#line 81 "inform7/Chapter 15/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 15/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 15/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 15/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 15/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__sentence_problem(_P_(C15LPCantScaleYet),
"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 15/Scaled Arithmetic Values.w"
else
{
#line 174 "inform7/Chapter 15/Scaled Arithmetic Values.w"
if (((sc->int_scalar != 1) || (sc->real_scalar != 1.0)) &&
((alt) && (sc->scaling_mode == LP_SCALED_AT)))
Problems__sentence_problem(_P_(C15LPCantScaleTwice),
"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 15/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 15/Scaled Arithmetic Values.w"
else
{
#line 227 "inform7/Chapter 15/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 15/Scaled Arithmetic Values.w"
;
}
#line 141 "inform7/Chapter 15/Scaled Arithmetic Values.w"
;
return rescale_the_others_by_this;
}
#line 262 "inform7/Chapter 15/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 15/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 15/Scaled Arithmetic Values.w"
int Kinds__Scalings__get_integer_multiplier(scaling_transformation sc) {
return sc.int_M;
}
#line 316 "inform7/Chapter 15/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 15/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 15/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 15/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 15/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 15/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 (Code__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 15/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 15/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 15/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 15/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 15/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 15/Scaled Arithmetic Values.w"
else
{
#line 553 "inform7/Chapter 15/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 15/Scaled Arithmetic Values.w"
;
}
#line 492 "inform7/Chapter 15/Scaled Arithmetic Values.w"
;
OUTDENT; WRITE("}\n");
} else {
WRITE("REAL_NUMBER_TY_Say(%s);", V_var);
}
}
#line 563 "inform7/Chapter 15/Scaled Arithmetic Values.w"
void Kinds__Scalings__I6_real_literal(OUTPUT_STREAM, double x) {
WRITE("$");
if (x > 0) WRITE("+");
WRITE("%g", x);
}
#line 24 "inform7/Chapter 15/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 35 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_heap_allocator(OUTPUT_STREAM) {
{
#line 49 "inform7/Chapter 15/Runtime Support for Kinds.w"
int max_heap = 1;
if (total_heap_allocation < Config__Inclusions__get_dynamic_memory_allocation())
total_heap_allocation = Config__Inclusions__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 36 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
}
#line 64 "inform7/Chapter 15/Runtime Support for Kinds.w"
STREAM BCON_struct;
STREAM *BCON = NULL;
int block_constant_counter = 0;
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);
STREAM_WRITE(BCON, "Array %s --> ", block_constant_id);
return BCON;
}
void Kinds__RunTime__end_block_constant(kind *K) {
STREAM_WRITE(BCON, ";\n");
}
#line 88 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_block_constants(OUTPUT_STREAM) {
if (BCON) {
STREAM_COPY(OUT, BCON);
STREAM_CLOSE(BCON);
}
}
#line 105 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_heap_allocation(OUTPUT_STREAM, kind *K, int multiplier,
int stack_offset) {
if (Kinds__uses_pointer_values(K) == FALSE)
internal_error("unable to allocate heap storage for this kind of value");
if (Kinds__get_heap_size_estimate(K) == 0)
internal_error("no heap storage estimate for this kind of value");
total_heap_allocation += (Kinds__get_heap_size_estimate(K) + 8)*multiplier;
if (stack_offset >= 0) WRITE("BlkValueCreateOnStack(%d, ", stack_offset);
else WRITE("BlkValueCreate(");
Kinds__RuntimeIDs__compile_strong(OUT, K);
if (Kinds__get_construct(K) == CON_relation)
Kinds__RuntimeIDs__precompile_default_value(K);
WRITE(")");
}
#line 131 "inform7/Chapter 15/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 (Code__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 (Code__VirtualMachines__is_16_bit())
WRITE("(%d) ", 0x100*n + flags);
else
WRITE("(%d) ", 0x1000000*n + 0x10000*flags);
Kinds__RuntimeIDs__compile_weak(OUT, K);
WRITE(" ");
WRITE("MAX_POSITIVE_NUMBER ");
}
#line 154 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_data_type_support_routines(OUTPUT_STREAM) {
kind *K;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__lt(K, K_object)) continue;
char *printing_rule_name = Kinds__get_name_of_printing_rule(K);
if (Kinds__stored_as(K) == NULL)
if (Kinds__is_an_enumeration(K)) {
{
#line 214 "inform7/Chapter 15/Runtime Support for Kinds.w"
OUT = Code__Routines__begin(OUT, printing_rule_name);
Code__LocalVariables__add_named_call("value");
WRITE("switch(value) {\n"); INDENT;
instance *I;
LOOP_OVER_INSTANCES(I, K) {
int k;
WRITE("%s: print \"", Data__Instances__identifier(I));
int nw1, nw2;
Data__Instances__get_name_in_play(I, &nw1, &nw2, FALSE);
for (k=nw1; k<=nw2; k++) {
Formats__Inform6__compile_string(OUT, Text__word_raw_text(k), 0);
if (k < nw2) WRITE(" ");
}
WRITE("\";\n");
}
/* this default case should never be needed, unless the user has blundered at the I6 level: */
int w1, w2;
Kinds__get_name(K, &w1, &w2, FALSE);
WRITE("default: print \"<illegal ");
if (w1 >= 0) Text__print_text_to_stream(w1, w2, OUT); else WRITE("value");
WRITE(">\";\n");
OUTDENT; WRITE("}\n");
OUT = Code__Routines__end(OUT);
}
#line 161 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
{
#line 253 "inform7/Chapter 15/Runtime Support for Kinds.w"
int j = Kinds__get_highest_valid_value_as_integer(K);
char rname[32];
sprintf(rname, "A_%s", printing_rule_name);
OUT = Code__Routines__begin(OUT, rname);
Code__LocalVariables__add_named_call("value");
WRITE("return (value %% %d)+1;\n", j);
OUT = Code__Routines__end(OUT);
sprintf(rname, "B_%s", printing_rule_name);
OUT = Code__Routines__begin(OUT, rname);
Code__LocalVariables__add_named_call("value");
WRITE("return ((value+%d) %% %d)+1;\n", j-2, j);
OUT = Code__Routines__end(OUT);
}
#line 162 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
{
#line 277 "inform7/Chapter 15/Runtime Support for Kinds.w"
char rname[32];
sprintf(rname, "R_%s", printing_rule_name);
OUT = Code__Routines__begin(OUT, rname);
Code__LocalVariables__add_named_call("a");
Code__LocalVariables__add_named_call("b");
if (Kinds__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__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 = Code__Routines__end(OUT);
}
#line 163 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
}
}
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__is_built_in(K)) continue;
if (Kinds__lt(K, K_object)) continue;
char *printing_rule_name = Kinds__get_name_of_printing_rule(K);
if (Kinds__is_an_enumeration(K)) continue;
if (Kinds__stored_as(K) == NULL) {
if (Kinds__is_quasinumerical(K)) {
{
#line 201 "inform7/Chapter 15/Runtime Support for Kinds.w"
OUT = Code__Routines__begin(OUT, printing_rule_name);
Code__LocalVariables__add_named_call("value");
if (Kinds__list_of_literal_forms(K))
Semantics__Nouns__LiteralPatterns__printing_routine(OUT,
Kinds__list_of_literal_forms(K));
else {
WRITE(";\n"); INDENT; WRITE("print value;\n");
}
OUT = Code__Routines__end(OUT);
}
#line 173 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
{
#line 277 "inform7/Chapter 15/Runtime Support for Kinds.w"
char rname[32];
sprintf(rname, "R_%s", printing_rule_name);
OUT = Code__Routines__begin(OUT, rname);
Code__LocalVariables__add_named_call("a");
Code__LocalVariables__add_named_call("b");
if (Kinds__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__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 = Code__Routines__end(OUT);
}
#line 174 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
} else {
{
#line 190 "inform7/Chapter 15/Runtime Support for Kinds.w"
OUT = Code__Routines__begin(OUT, printing_rule_name);
Code__LocalVariables__add_named_call("value");
WRITE("! weak kind ID: %d\n", printing_rule_name, Kinds__RuntimeIDs__weak(K));
WRITE("print value;\n");
OUT = Code__Routines__end(OUT);
}
#line 176 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
}
}
}
{
#line 297 "inform7/Chapter 15/Runtime Support for Kinds.w"
{
#line 309 "inform7/Chapter 15/Runtime Support for Kinds.w"
OUT = Code__Routines__begin(OUT, "PrintKindValuePair");
Code__LocalVariables__add_named_call("k");
Code__LocalVariables__add_named_call("v");
WRITE("k = KindAtomic(k);\n");
WRITE(" switch(k) {\n"); INDENT;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__lt(K, K_object)) continue;
WRITE("%d: print (%s) v;\n",
Kinds__RuntimeIDs__weak(K),
Kinds__get_name_of_printing_rule(K));
}
WRITE("default: print v;\n");
OUTDENT; WRITE("}\n");
OUT = Code__Routines__end(OUT);
}
#line 297 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
{
#line 329 "inform7/Chapter 15/Runtime Support for Kinds.w"
OUT = Code__Routines__begin(OUT, "DefaultValueOfKOV");
Code__LocalVariables__add_named_call("sk");
Code__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__lt(K, K_object)) continue;
if (Kinds__definite(K)) {
WRITE("%d: return ", Kinds__RuntimeIDs__weak(K));
if (Kinds__uses_pointer_values(K))
WRITE("BlkValueCreate(sk)");
else
Kinds__compile_default_value(OUT, K, -1, -1, "list entry");
WRITE(";\n");
}
}
WRITE("default: return 0;\n");
OUTDENT; WRITE("}\n");
OUT = Code__Routines__end(OUT);
}
#line 298 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
{
#line 358 "inform7/Chapter 15/Runtime Support for Kinds.w"
OUT = Code__Routines__begin(OUT, "KOVComparisonFunction");
Code__LocalVariables__add_named_call("k");
WRITE("k = KindAtomic(k);\n");
WRITE("switch(k) {\n"); INDENT;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__lt(K, K_object)) continue;
if (Kinds__definite(K)) {
if (Kinds__uses_signed_comparisons(K) == FALSE)
WRITE("%d: return %s;\n",
Kinds__RuntimeIDs__weak(K),
Kinds__get_comparison_routine(K));
}
}
WRITE("default: return 0;\n");
OUTDENT; WRITE("}\n");
OUT = Code__Routines__end(OUT);
}
#line 299 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
{
#line 378 "inform7/Chapter 15/Runtime Support for Kinds.w"
OUT = Code__Routines__begin(OUT, "KOVDomainSize");
Code__LocalVariables__add_named_call("k");
WRITE("k = KindAtomic(k);\n");
WRITE("switch(k) {\n"); INDENT;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__lt(K, K_object)) continue;
if (Kinds__is_an_enumeration(K))
WRITE("%d: return %d;\n", Kinds__RuntimeIDs__weak(K),
Kinds__get_highest_valid_value_as_integer(K));
}
WRITE("default: return 0;\n");
OUTDENT; WRITE("}\n");
OUT = Code__Routines__end(OUT);
}
#line 300 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
{
#line 396 "inform7/Chapter 15/Runtime Support for Kinds.w"
OUT = Code__Routines__begin(OUT, "KOVIsBlockValue");
Code__LocalVariables__add_named_call("k");
WRITE("k = KindAtomic(k);\n");
WRITE("if (k == ");
int j = 0;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__lt(K, K_object)) continue;
if (Kinds__uses_pointer_values(K)) {
if (j++ > 0) WRITE(" or ");
WRITE("%d", Kinds__RuntimeIDs__weak(K));
}
}
WRITE(") rtrue;\n");
WRITE("rfalse;\n");
OUT = Code__Routines__end(OUT);
}
#line 301 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
{
#line 417 "inform7/Chapter 15/Runtime Support for Kinds.w"
OUT = Code__Routines__begin(OUT, "KOVSupportFunction");
Code__LocalVariables__add_named_call("k");
Code__LocalVariables__add_named_call("fail");
WRITE("k = KindAtomic(k);\n");
WRITE("switch(k) {\n"); INDENT;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__uses_pointer_values(K)) {
WRITE("%d: return ", Kinds__RuntimeIDs__weak(K));
Kinds__write_support_routine_name(OUT, K);
WRITE(";\n");
}
}
OUTDENT; WRITE("}\n");
WRITE("if (fail) BlkValueError(fail);\n");
WRITE("rfalse;\n");
OUT = Code__Routines__end(OUT);
}
#line 302 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
}
#line 181 "inform7/Chapter 15/Runtime Support for Kinds.w"
;
}
#line 439 "inform7/Chapter 15/Runtime Support for Kinds.w"
void Kinds__RunTime__I7_Kind_Name_routine(OUTPUT_STREAM) {
kind *K;
OUT = Code__Routines__begin(OUT, "I7_Kind_Name");
Code__LocalVariables__add_named_call("k");
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__lt(K, K_object)) {
int w1, w2;
Kinds__get_name(K, &w1, &w2, FALSE);
WRITE("if (k == %s) print \"", Kinds__I6_classname(K));
Text__print_raw_text_to_stream(w1, w2, OUT);
WRITE("\";\n");
}
}
OUT = Code__Routines__end(OUT);
}
#line 458 "inform7/Chapter 15/Runtime Support for Kinds.w"
int VM_non_support_problem_issued = FALSE;
void Kinds__notify_of_use(kind *K) {
if (Code__VirtualMachines__supports(K) == FALSE) {
if (VM_non_support_problem_issued == FALSE) {
VM_non_support_problem_issued = TRUE;
Problems__handmade_problem(_P_(C15KindRequiresGlulx));
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 25 "inform7/Chapter 15/Kinds Index.w"
void Kinds__Index__index_kinds(int pass) {
int priority;
if (pass == 1) {
INDEX("<p></p>");
tabulating_kinds_index = TRUE;
Formats__HTML__begin_wide_html_table(ifl);
{
#line 111 "inform7/Chapter 15/Kinds Index.w"
INDEX("<tr bgcolor=\"#888\"><td height=\"1\" colspan=\"5\" cellpadding=\"0\"></td></tr>");
}
#line 31 "inform7/Chapter 15/Kinds Index.w"
;
{
#line 89 "inform7/Chapter 15/Kinds Index.w"
Formats__HTML__first_html_column_nowrap(ifl, 0, "#e0e0e0");
INDEX("<b>basic kinds</b>");
index_kind_col_head("default value", "default");
index_kind_col_head("repeat", "repeat");
index_kind_col_head("props", "props");
index_kind_col_head("under", "under");
Formats__HTML__end_html_row(ifl);
}
#line 32 "inform7/Chapter 15/Kinds Index.w"
;
{
#line 111 "inform7/Chapter 15/Kinds Index.w"
INDEX("<tr bgcolor=\"#888\"><td height=\"1\" colspan=\"5\" cellpadding=\"0\"></td></tr>");
}
#line 33 "inform7/Chapter 15/Kinds Index.w"
;
{
#line 133 "inform7/Chapter 15/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 15/Kinds Index.w"
;
}
for (priority = 1; priority <= LOWEST_INDEX_PRIORITY; priority++) {
kind *K;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__lt(K, K_object)) continue;
if (priority == Kinds__get_index_priority(K)) {
if (Kinds__definite(K)) {
switch (pass) {
case 1:
{
#line 116 "inform7/Chapter 15/Kinds Index.w"
char *repeat = "cross", *props = "cross", *under = "cross";
int shaded = FALSE;
if ((Kinds__get_highest_valid_value_as_integer(K) == 0) &&
(Kinds__indexed_grey_if_empty(K)))
shaded = TRUE;
if (Kinds__compile_domain_possible(K)) repeat = "tick";
if (Kinds__has_properties(K)) props = "tick";
if (Kinds__offers_I6_GPR(K)) under = "tick";
Kinds__Index__begin_chart_row();
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 15/Kinds Index.w"
; break;
case 2:
{
#line 168 "inform7/Chapter 15/Kinds Index.w"
Formats__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__get_documentation_reference(K))
Index__doc_link(Kinds__get_documentation_reference(K)); /* blue help icon, if any */
INDEX("</p>");
if (Kinds__is_proper_constructor(K)) {
Formats__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 15/Kinds Index.w"
;
Formats__HTML__open_para(ifl, 1, "tight");
{
#line 206 "inform7/Chapter 15/Kinds Index.w"
int f = FALSE;
INDEX("<i>Matches:</i> ");
kind *K2;
LOOP_OVER_BASE_KINDS(K2) {
if ((Kinds__is_kind_of_kind(K2)) &&
(Kinds__le(K, K2)) &&
(Kinds__eq(K2, K_word_value) == FALSE) &&
(Kinds__eq(K2, K_pointer_value) == FALSE)) {
if (f) INDEX(", ");
Kinds__Index__index_kind(K2, FALSE, TRUE);
f = TRUE;
}
}
INDEX("<br>");
}
#line 48 "inform7/Chapter 15/Kinds Index.w"
;
{
#line 233 "inform7/Chapter 15/Kinds Index.w"
char *explanation = Kinds__get_specification_text(K);
if (explanation) INDEX("%s<br>\n", explanation);
World__Inferences__index(Kinds__as_subject(K), FALSE);
}
#line 49 "inform7/Chapter 15/Kinds Index.w"
;
{
#line 198 "inform7/Chapter 15/Kinds Index.w"
if (Kinds__list_of_literal_forms(K)) {
Semantics__Nouns__LiteralPatterns__index_all(K);
INDEX("<br>");
}
}
#line 50 "inform7/Chapter 15/Kinds Index.w"
;
{
#line 225 "inform7/Chapter 15/Kinds Index.w"
if (Kinds__is_an_enumeration(K)) {
INDEX("</p>");
Data__Objects__index_instances(K, 1);
}
}
#line 51 "inform7/Chapter 15/Kinds Index.w"
;
INDEX("</p>\n"); break;
}
if (Kinds__eq(K, K_object))
{
#line 81 "inform7/Chapter 15/Kinds Index.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__eq(Kinds__super(K), K_object))
Data__Objects__index(NULL, K, 2, (pass == 1)?FALSE:TRUE);
}
#line 54 "inform7/Chapter 15/Kinds Index.w"
;
}
}
}
if ((priority == 1) || (priority == 6) || (priority == 7)) {
if (pass == 1) {
{
#line 111 "inform7/Chapter 15/Kinds Index.w"
INDEX("<tr bgcolor=\"#888\"><td height=\"1\" colspan=\"5\" cellpadding=\"0\"></td></tr>");
}
#line 60 "inform7/Chapter 15/Kinds Index.w"
;
if (priority == 7) {
{
#line 100 "inform7/Chapter 15/Kinds Index.w"
Formats__HTML__first_html_column_nowrap(ifl, 0, "#e0e0e0");
INDEX("<b>making new kinds from old</b>");
index_kind_col_head("default value", "default");
index_kind_col_head("", NULL);
index_kind_col_head("", NULL);
index_kind_col_head("", NULL);
Formats__HTML__end_html_row(ifl);
}
#line 62 "inform7/Chapter 15/Kinds Index.w"
;
{
#line 111 "inform7/Chapter 15/Kinds Index.w"
INDEX("<tr bgcolor=\"#888\"><td height=\"1\" colspan=\"5\" cellpadding=\"0\"></td></tr>");
}
#line 63 "inform7/Chapter 15/Kinds Index.w"
;
}
} else INDEX("<hr>");
}
}
if (pass == 1) {
{
#line 111 "inform7/Chapter 15/Kinds Index.w"
INDEX("<tr bgcolor=\"#888\"><td height=\"1\" colspan=\"5\" cellpadding=\"0\"></td></tr>");
}
#line 70 "inform7/Chapter 15/Kinds Index.w"
;
Formats__HTML__end_html_table(ifl);
tabulating_kinds_index = FALSE;
} else {
{
#line 240 "inform7/Chapter 15/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 15/Kinds Index.w"
;
}
}
#line 253 "inform7/Chapter 15/Kinds Index.w"
void index_kind_col_head(char *name, char *anchor) {
Formats__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 15/Kinds Index.w"
int striper = FALSE;
void Kinds__Index__begin_chart_row(void) {
char *col = NULL;
if (striper) col = "#f0f0ff";
striper = striper?FALSE:TRUE;
Formats__HTML__first_html_column_nowrap(ifl, 0, col);
}
#line 285 "inform7/Chapter 15/Kinds Index.w"
int 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__is_quasinumerical(K))
INDEX("&nbsp;<a href=\"Kinds.html?segment2\"><img border=0 src=inform:/doc_images/calc1.png></a>");
if (Kinds__get_documentation_reference(K))
Index__doc_link(Kinds__get_documentation_reference(K));
int i = Data__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 15/Kinds Index.w"
void Kinds__Index__end_chart_row(int shaded, kind *K,
char *tick1, char *tick2, char *tick3) {
if (tick1) Formats__HTML__next_html_column(ifl, 0);
else Formats__HTML__next_html_column_spanning(ifl, 0, 4);
if (shaded) INDEX("<font color=\"%s\">", KINDS_INDEX_SHADE);
{
#line 330 "inform7/Chapter 15/Kinds Index.w"
int found = FALSE;
instance *inst;
LOOP_OVER_INSTANCES(inst, K) {
Data__Instances__index_name(inst);
found = TRUE;
break;
}
if (found == FALSE) {
char *p = Kinds__get_index_default_value(K);
if (strcmp(p, "<0-in-literal-pattern>") == 0)
{
#line 351 "inform7/Chapter 15/Kinds Index.w"
if (Kinds__list_of_literal_forms(K))
Semantics__Nouns__LiteralPatterns__index_value(
Kinds__list_of_literal_forms(K), 0);
else
INDEX("--");
}
#line 340 "inform7/Chapter 15/Kinds Index.w"
else if (strcmp(p, "<first-constant>") == 0)
INDEX("--");
else INDEX(p);
}
}
#line 308 "inform7/Chapter 15/Kinds Index.w"
;
if (shaded) INDEX("</font>");
if (tick1) {
Formats__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);
Formats__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);
Formats__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);
}
Formats__HTML__end_html_row(ifl);
}
#line 360 "inform7/Chapter 15/Kinds Index.w"
void Kinds__Index__index_kind(kind *K, int plural, int with_links) {
if (K == NULL) return;
int w1 = -1, w2 = -1;
Kinds__get_name(K, &w1, &w2, plural);
if (w1 >= 0) {
if (Kinds__is_proper_constructor(K)) {
{
#line 382 "inform7/Chapter 15/Kinds Index.w"
int length = w2 - w1 + 1, tinted = TRUE;
int i, first_stroke = -1, last_stroke = -1;
for (i=0; i<length; i++) {
if (Text__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 (Text__word(w1+j) == Text__word(w1+i))
untinted = TRUE;
if (untinted) INDEX("</font>");
if (i>from) INDEX(" ");
char *p = Text__Vocabulary__get_exemplar(Text__word(w1+i), FALSE);
if (Text__word(w1+i) == CAPITAL_K_V) p = "K";
if (Text__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 366 "inform7/Chapter 15/Kinds Index.w"
;
} else {
Text__print_text_to_stream(w1, w2, ifl);
if (with_links) {
int wn = w1;
if (Kinds__get_creating_sentence(K))
wn = Kinds__get_creating_sentence(K)->word_ref1;
Index__link(wn);
}
}
}
}
#line 181 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__make_type_IDs_table(void) {
type_ID_enlarge_types_table(INITIAL_ID_TABLE_SIZE);
Specifications__Taxa__set_source_name(UNKNOWN, "UNKNOWN");
Specifications__Taxa__permit_pair(UNKNOWN, UNKNOWN,
PARSED_SPCONTEXT + TYPE_PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Matching__create_species();
Specifications__Values__create_species();
Specifications__Storage__create_species();
Specifications__Conditions__create_species();
Specifications__Commands__create_species();
Kinds__Interpreter__start();
}
#line 204 "inform7/Chapter 16/Taxonomy of Specifications.w"
int extent_of_type_tables = 0; /* call this number $X$ */
taxon *type_IDs_table = NULL; /* 1-dimensional array of $X$ entries */
taxa_observations *table_of_observations = NULL; /* 2-dimensional array of $X^2$ entries */
#line 213 "inform7/Chapter 16/Taxonomy of Specifications.w"
taxa_observations *type_ID_pair_rules(int r, int s) {
if (table_of_observations == NULL) internal_error("no table of observations");
return &(table_of_observations[r*extent_of_type_tables + s]);
}
#line 224 "inform7/Chapter 16/Taxonomy of Specifications.w"
void type_ID_enlarge_types_table(int to_size) {
int from_size = extent_of_type_tables;
taxon *tt; /* the new larger type ID table */
taxa_observations *tc; /* the new larger table of observations */
{
#line 238 "inform7/Chapter 16/Taxonomy of Specifications.w"
if (to_size <= from_size)
internal_error("type tables not increased in size");
tt = (taxon *)
(Memory__I7_calloc(to_size, sizeof(taxon), TYPE_TABLES_MREASON));
tc = (taxa_observations *)
(Memory__I7_calloc(to_size*to_size, sizeof(taxa_observations), TYPE_TABLES_MREASON));
}
#line 228 "inform7/Chapter 16/Taxonomy of Specifications.w"
;
{
#line 248 "inform7/Chapter 16/Taxonomy of Specifications.w"
int i, j;
for (i=0; i<from_size; i++)
tt[i] = type_IDs_table[i];
for (i=0; i<from_size; i++)
for (j=0; j<from_size; j++)
tc[i*to_size + j]
= table_of_observations[i*from_size + j];
}
#line 229 "inform7/Chapter 16/Taxonomy of Specifications.w"
;
{
#line 261 "inform7/Chapter 16/Taxonomy of Specifications.w"
int i, j;
for (i=from_size; i<to_size; i++)
type_ID_details_initialise(&(tt[i]), i);
for (i=0; i<to_size; i++)
for (j=0; j<to_size; j++)
if ((i>=from_size) || (j>=from_size))
tpr_initialise(&(tc[i*to_size + j]));
}
#line 230 "inform7/Chapter 16/Taxonomy of Specifications.w"
;
{
#line 275 "inform7/Chapter 16/Taxonomy of Specifications.w"
if (from_size > 0) {
Memory__I7_free(type_IDs_table, TYPE_TABLES_MREASON);
Memory__I7_free(table_of_observations, TYPE_TABLES_MREASON);
}
}
#line 231 "inform7/Chapter 16/Taxonomy of Specifications.w"
;
{
#line 283 "inform7/Chapter 16/Taxonomy of Specifications.w"
type_IDs_table = tt;
table_of_observations = tc;
extent_of_type_tables = to_size;
}
#line 232 "inform7/Chapter 16/Taxonomy of Specifications.w"
;
}
#line 291 "inform7/Chapter 16/Taxonomy of Specifications.w"
void type_ID_details_initialise(taxon *tidr, int i) {
tidr->species_flags = 0;
sprintf(tidr->source_name, "<type-%d>", i);
tidr->no_species_in_this_family = 0;
tidr->family_of_which_this_is_species = UNKNOWN;
}
void tpr_initialise(taxa_observations *tpr) {
int i;
tpr->legal_contexts = 0;
for (i=0; i<NO_SPEC_CONTEXTS; i++) tpr->observations[i] = NULL;
}
#line 310 "inform7/Chapter 16/Taxonomy of Specifications.w"
int Specifications__Taxa__exists(int t) {
if ((t < 0) || (t >= extent_of_type_tables)) return FALSE;
return TRUE;
}
#line 320 "inform7/Chapter 16/Taxonomy of Specifications.w"
int Specifications__Taxa__is_family_ID(int t) {
if ((Specifications__Taxa__exists(t)) && (type_IDs_table[t].no_species_in_this_family > 0))
return TRUE;
return FALSE;
}
#line 330 "inform7/Chapter 16/Taxonomy of Specifications.w"
int Specifications__Taxa__get_family_of_species(int t) {
if (Specifications__Taxa__exists(t)) return type_IDs_table[t].family_of_which_this_is_species;
return UNKNOWN;
}
#line 338 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__set_flag(int t, int f) {
if (Specifications__Taxa__exists(t)) type_IDs_table[t].species_flags |= f;
else internal_error("tried to set type ID flags for nonexistent type ID");
}
int Specifications__Taxa__test_flag(int t, int f) {
if (Specifications__Taxa__exists(t) == FALSE) return FALSE;
if ((type_IDs_table[t].species_flags) & f) return TRUE;
return FALSE;
}
#line 362 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__log(int id) {
if ((id <= 0) || (id >= extent_of_type_tables)) LOG("ILLEGAL-TAXON-%d", id);
else if (id == 1) LOG("UNKNOWN");
else LOG("%s", type_IDs_table[id].source_name);
}
#line 371 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__set_source_name(int id, char *d) {
Extensions__IDs__truncated_strcpy(type_IDs_table[id].source_name, d, 31);
}
#line 378 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__set_parsing_names(int t,
vocabulary_entry *singular, vocabulary_entry *plural) {
if (singular) {
Text__Vocabulary__set_flags(singular, KIND_FAST_MC);
Text__Vocabulary__set_literal_number_value(singular, -t);
Text__Languages__mark_vocabulary(singular, k_kind_NTM);
}
if (plural) {
Text__Vocabulary__set_flags(plural, KIND_FAST_MC);
Text__Vocabulary__set_literal_number_value(plural, -t);
Text__Languages__mark_vocabulary(plural, k_kind_NTM);
}
}
#line 401 "inform7/Chapter 16/Taxonomy of Specifications.w"
char *name_of_spec_context(int context) {
switch(context) {
case TYPE_EXPECTED_SPCONTEXT: return "type expected";
case TYPE_FOUND_SPCONTEXT: return "type found";
case COMPILED_SPCONTEXT: return "value compiled";
case PARSED_SPCONTEXT: return "value parsed";
case TYPE_PARSED_SPCONTEXT: return "type parsed";
default: return "miscellaneous";
}
}
void Specifications__Taxa__permit_pair(int a, int b, int map) {
type_ID_pair_rules(a, b)->legal_contexts = map;
type_IDs_table[a].no_species_in_this_family++;
type_IDs_table[b].family_of_which_this_is_species = a;
}
#line 424 "inform7/Chapter 16/Taxonomy of Specifications.w"
int observed_before = FALSE;
void Specifications__Taxa__observe(specification *spec, int context) {
int fmy = Specifications__get_family(spec), spc = Specifications__get_species(spec);
int i, j, k, ix;
ix=0; j=context; while (j != 1) { ix++; j = j/2; }
if ((fmy <= 0) || (fmy >= 50) ||
(spc <= 0) || (spc >= extent_of_type_tables)) {
LOG("Illegal taxon (context %d): %d/%d\n", context, fmy, spc);
LOG("Error on: $X", spec);
internal_error("type ID out of legal range");
}
if ((type_ID_pair_rules(fmy, spc)->legal_contexts
& context) == 0) {
LOG("SP ID combination illegal in context %s: %s/%s\n",
name_of_spec_context(context),
type_IDs_table[fmy].source_name,
type_IDs_table[spc].source_name);
LOG("Error on: $X (allows %04x)\n", spec,
type_ID_pair_rules(fmy, spc)->legal_contexts);
internal_error("Illegal SP ID combination");
}
if (observed_before == FALSE) {
observed_before = TRUE;
for (i=0; i<extent_of_type_tables; i++)
for (j=0; j<extent_of_type_tables; j++)
for (k=0; k<NO_SPEC_CONTEXTS; k++)
type_ID_pair_rules(i, j)->observations[k] = NULL;
}
type_ID_pair_rules(fmy, spc)->observations[ix] = spec;
}
#line 469 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__report_pairs_observed(void) {
int i, j, k, context;
if (Log__Aspects__on(SPECIFICATION_USAGE_DA) == FALSE) return;
for (i=0; i<extent_of_type_tables; i++)
for (j=0; j<extent_of_type_tables; j++)
for (k=0, context=1; k<NO_SPEC_CONTEXTS; k++, context = context*2) {
if (type_ID_pair_rules(i, j)->observations[k]) {
LOG("SP used: %s/%s in %s ",
type_IDs_table[i].source_name, type_IDs_table[j].source_name,
name_of_spec_context(context));
if ((type_ID_pair_rules(i, j)->legal_contexts & context) == 0) LOG("!! ");
LOG("$S\n", type_ID_pair_rules(i, j)->observations[k]);
}
}
}
#line 489 "inform7/Chapter 16/Taxonomy of Specifications.w"
void Specifications__Taxa__report_pairs_allowed(void) {
int i, j;
if (Log__Aspects__on(SPECIFICATION_PERMISSIONS_DA) == FALSE) return;
for (i=0; i<extent_of_type_tables; i++) {
int flag = FALSE;
for (j=0; j<extent_of_type_tables; j++)
if (type_ID_pair_rules(i, j)->legal_contexts) {
if (flag == FALSE) {
LOG("%s - family with species:\n", type_IDs_table[i].source_name);
flag = TRUE;
}
LOG(" %s\n", type_IDs_table[j].source_name);
}
flag = FALSE;
for (j=0; j<extent_of_type_tables; j++)
if (type_ID_pair_rules(j, i)->legal_contexts) {
if (flag == FALSE) {
LOG("%s - species of", type_IDs_table[i].source_name);
flag = TRUE;
}
LOG(" %s", type_IDs_table[j].source_name);
}
if (flag) { LOG("\n"); }
}
}
#line 111 "inform7/Chapter 16/Specifications.w"
specification *Specifications__new(int family, int species) {
specification *spec = CREATE(specification);
spec->spec_packed_record = 0;
spec->family_and_species = family + SPECIES_MULTIPLIER*species;
spec->associated_kind = NULL;
spec->word_ref1 = -1; spec->word_ref2 = -1;
spec->which_structure = NULL_GENERAL_POINTER;
spec->condition_tense = NULL;
spec->proposition = NULL;
spec->docket = NULL;
new_spec_count++;
return spec;
}
#line 129 "inform7/Chapter 16/Specifications.w"
specification *Specifications__copy(specification *spec) {
specification *sts = CREATE(specification);
*sts = *spec;
copied_spec_count++;
return sts;
}
#line 144 "inform7/Chapter 16/Specifications.w"
void Specifications__coerce_to(specification *spec, int new_family, int new_species) {
spec->family_and_species = new_family + SPECIES_MULTIPLIER*new_species;
Specifications__set_flag(spec, COERCED_SPFLAG);
}
#line 154 "inform7/Chapter 16/Specifications.w"
int Specifications__species_is(specification *spec, int species) {
if ((spec) && ((spec->family_and_species)/SPECIES_MULTIPLIER == species)) return TRUE;
return FALSE;
}
int Specifications__family_is(specification *spec, int family) {
if ((spec) && ((spec->family_and_species)%SPECIES_MULTIPLIER == family)) return TRUE;
return FALSE;
}
#line 167 "inform7/Chapter 16/Specifications.w"
int Specifications__get_species(specification *spec) {
if (spec == NULL) return UNKNOWN;
return (spec->family_and_species)/SPECIES_MULTIPLIER;
}
int Specifications__get_family(specification *spec) {
if (spec == NULL) return UNKNOWN;
return (spec->family_and_species)%SPECIES_MULTIPLIER;
}
#line 181 "inform7/Chapter 16/Specifications.w"
int spec_test_ability(specification *spec, int f) {
if (spec == NULL) return FALSE;
if (Specifications__Taxa__test_flag(Specifications__get_family(spec), f)) return TRUE;
if (Specifications__Taxa__test_flag(Specifications__get_species(spec), f)) return TRUE;
return FALSE;
}
#line 193 "inform7/Chapter 16/Specifications.w"
int Specifications__is_UNKNOWN(specification *spec) {
if (Specifications__family_is(spec, UNKNOWN)) return TRUE;
return FALSE;
}
specification *Specifications__Unknown__new(int w1, int w2) {
specification *spec = Specifications__new(UNKNOWN, UNKNOWN);
spec->word_ref1 = w1; spec->word_ref2 = w2;
return spec;
}
void Specifications__Unknown__coerce(specification *spec) {
if (spec == NULL) internal_error("tried to invalidate null spec");
Specifications__coerce_to(spec, UNKNOWN, UNKNOWN);
}
#line 216 "inform7/Chapter 16/Specifications.w"
void Specifications__make_actual(specification *spec) {
Specifications__clear_flag(spec, GENERIC_DATA_SPFLAG);
}
void Specifications__make_generic(specification *spec) {
Specifications__set_flag(spec, GENERIC_DATA_SPFLAG);
}
#line 226 "inform7/Chapter 16/Specifications.w"
int Specifications__is_actual(specification *spec) {
return (Specifications__test_flag(spec, GENERIC_DATA_SPFLAG))?FALSE:TRUE;
}
int Specifications__is_generic(specification *spec) {
return Specifications__test_flag(spec, GENERIC_DATA_SPFLAG);
}
#line 238 "inform7/Chapter 16/Specifications.w"
void Specifications__set_flag(specification *spec, int flag) {
if (spec == NULL) internal_error("tried to set flag for null SP");
spec->spec_packed_record = (spec->spec_packed_record) | flag;
}
void Specifications__clear_flag(specification *spec, int flag) {
if (spec == NULL) internal_error("tried to clear flag for null SP");
spec->spec_packed_record = (spec->spec_packed_record) & (~flag);
}
int Specifications__test_flag(specification *spec, int flag) {
int f = (spec)?(spec->spec_packed_record):0;
if (f & flag) return TRUE;
return FALSE;
}
#line 257 "inform7/Chapter 16/Specifications.w"
void Specifications__set_data(specification *spec, int purpose, int data) {
if (spec == NULL) internal_error("tried to set data for null SP");
if (data == -1) { purpose = NO_SPDATA; data = 0; }
if ((data < 0) || (data >= 65536)) internal_error("tried to set data out of range");
spec->spec_packed_record = ((spec->spec_packed_record) & (~(SPDATA_ID_MASK + SPDATA_MASK)))
+ BASE_OF_SPDATA_ID*purpose
+ BASE_OF_SPDATA*data;
}
int Specifications__get_data(specification *spec, int purpose) {
if (spec == NULL) return -1;
int there = ((spec->spec_packed_record) & SPDATA_ID_MASK)/BASE_OF_SPDATA_ID;
if (there == NO_SPDATA) return -1;
if (there == purpose) return ((spec->spec_packed_record) & SPDATA_MASK)/BASE_OF_SPDATA;
internal_error("tried to fetch data with the wrong SPDATA ID");
return -1;
}
#line 281 "inform7/Chapter 16/Specifications.w"
int Specifications__get_argc(specification *spec) {
if (spec == NULL) internal_error("tried to read argument of null SP");
return ((spec->spec_packed_record) & ARGC_MASK)/BASE_OF_ARGC;
}
specification *Specifications__get_argument(specification *spec, int c) {
if (spec == NULL) internal_error("tried to read argument of null SP");
if ((c<0) || (c>=MAXIMUM_SPEC_ARGUMENTS)) internal_error("tried to read bad argument of SP");
if (spec_test_ability(spec, ARGUMENTS_SPCFLAG) == FALSE)
internal_error("tried to read argument of bad SP");
if (c >= Specifications__get_argc(spec)) internal_error("tried to read missing argument of SP");
return spec->arguments[c];
}
void Specifications__set_argument(specification *spec, int c, specification *arg) {
if (spec == NULL) internal_error("tried to set argument of null SP");
if ((c<0) || (c>=MAXIMUM_SPEC_ARGUMENTS)) internal_error("tried to set bad argument of SP");
if (spec_test_ability(spec, ARGUMENTS_SPCFLAG) == FALSE)
internal_error("tried to set argument of bad SP");
if (c >= Specifications__get_argc(spec))
spec->spec_packed_record = ((spec->spec_packed_record) & (~(ARGC_MASK))) + (c+1)*BASE_OF_ARGC;
spec->arguments[c] = arg;
}
#line 310 "inform7/Chapter 16/Specifications.w"
kind *Specifications__get_kind(specification *spec) {
if (spec_test_ability(spec, ASSOCIATED_KIND_SPCFLAG)) return spec->associated_kind;
return NULL;
}
void Specifications__set_kind_of_value(specification *spec, kind *K) {
if (spec_test_ability(spec, ASSOCIATED_KIND_SPCFLAG)) spec->associated_kind = K;
else { LOG("$S\n", spec); internal_error("tried to set associated kind for wrong spec"); }
}
#line 323 "inform7/Chapter 16/Specifications.w"
general_pointer Specifications__get_structure_field(specification *spec) {
if (spec == NULL) internal_error("tried to get structure for null spec");
return spec->which_structure;
}
void Specifications__set_structure_field(specification *spec, general_pointer gp) {
if (spec == NULL) internal_error("tried to set structure for null spec");
spec->which_structure = gp;
}
#line 337 "inform7/Chapter 16/Specifications.w"
void Specifications__create_invocation_list(specification *spec) {
if (spec_test_ability(spec, INVLIST_SPCFLAG) == FALSE) {
LOG("SP: $X\n", spec); internal_error("can't create inv list for this spec");
}
ATTACH_TO_SPEC(spec, invocation_list, Code__Invocations__Lists__new());
}
void Specifications__set_invocation_list(specification *spec, invocation_list *invl) {
if (spec_test_ability(spec, INVLIST_SPCFLAG) == FALSE) {
LOG("SP: $X\n", spec); internal_error("can't create inv list for this spec");
}
ATTACH_TO_SPEC(spec, invocation_list, invl);
}
invocation_list *Specifications__invocation_list(specification *spec) {
if (spec_test_ability(spec, INVLIST_SPCFLAG))
return RETRIEVE_FROM_SPEC(spec, invocation_list);
return NULL;
}
int Specifications__has_invocation_list(specification *spec) {
if ((spec_test_ability(spec, INVLIST_SPCFLAG))
&& (VALID_POINTER_invocation_list(spec->which_structure))) return TRUE;
return FALSE;
}
#line 366 "inform7/Chapter 16/Specifications.w"
pcalc_prop *Specifications__get_proposition(specification *spec) {
if (spec_test_ability(spec, PROPOSITION_SPCFLAG)) return spec->proposition;
return NULL;
}
void Specifications__set_proposition(specification *spec, pcalc_prop *prop) {
if (spec_test_ability(spec, PROPOSITION_SPCFLAG)) spec->proposition = prop;
else { LOG("$S\n", spec); internal_error("tried to set proposition for wrong spec"); }
}
#line 379 "inform7/Chapter 16/Specifications.w"
description_docket *Specifications__get_docket(specification *spec) {
if (spec_test_ability(spec, DOCKET_SPCFLAG)) return spec->docket;
return NULL;
}
void Specifications__set_docket(specification *spec, description_docket *dd) {
if (spec_test_ability(spec, DOCKET_SPCFLAG)) spec->docket = dd;
else { LOG("$S\n", spec); internal_error("tried to set docket for wrong spec"); }
}
#line 392 "inform7/Chapter 16/Specifications.w"
kind *Specifications__get_kind_referred_to(specification *spec) {
kind *K = Specifications__evaluates_to(spec);
if (K) return K;
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
K = Specifications__Conditions__get_described_kind(spec);
if (K) return K;
pcalc_prop *prop = Specifications__get_proposition(spec);
K = Calculus__Variables__kind_of_variable_0(prop);
if (K) return K;
prop = Calculus__Propositions__from_spec(spec, FALSE);
K = Calculus__Variables__infer_kind_of_variable_0(prop);
if (K) return K;
return K_object;
}
return NULL;
}
#line 412 "inform7/Chapter 16/Specifications.w"
time_period *Specifications__get_condition_tense(specification *spec) {
if (spec_test_ability(spec, TENSE_SPCFLAG)) return spec->condition_tense;
return NULL;
}
void Specifications__set_condition_tense(specification *spec, time_period *tp) {
if (spec_test_ability(spec, TENSE_SPCFLAG)) spec->condition_tense = tp;
else { LOG("$S\n", spec); internal_error("tried to set tense for wrong spec"); }
}
#line 427 "inform7/Chapter 16/Specifications.w"
int Specifications__is_evaluating(specification *spec) {
return spec_test_ability(spec, EVALUATING_SPCFLAG);
}
kind *Specifications__evaluates_to(specification *spec) {
if (spec == NULL) return NULL;
switch(Specifications__get_family(spec)) {
case COMMAND_FMY: return Specifications__Commands__kind_when_COMMAND_is_evaluated(spec);
case CONDITION_FMY: return Specifications__Conditions__kind_when_CONDITION_is_evaluated(spec);
case MATCHING_FMY: return Specifications__Matching__kind_when_evaluated(spec);
case STORAGE_FMY: return Specifications__Storage__kind_when_STORAGE_is_evaluated(spec);
case VALUE_FMY: return Specifications__Values__kind_when_VALUE_is_evaluated(spec);
}
return NULL;
}
#line 447 "inform7/Chapter 16/Specifications.w"
int Specifications__is_phrasal(specification *spec) {
return spec_test_ability(spec, PHRASAL_SPCFLAG);
}
#line 457 "inform7/Chapter 16/Specifications.w"
void Specifications__write_out_in_English(OUTPUT_STREAM, specification *spec) {
if (spec == NULL) { WRITE("something unknown"); return; }
switch(Specifications__get_family(spec)) {
case COMMAND_FMY: Specifications__Commands__write_out_in_English(OUT, spec); return;
case CONDITION_FMY: Specifications__Conditions__write_out_in_English(OUT, spec); return;
case MATCHING_FMY: Specifications__Matching__write_out_in_English(OUT, spec); return;
case STORAGE_FMY: Specifications__Storage__write_out_in_English(OUT, spec); return;
case UNKNOWN: WRITE("something unrecognised"); return;
case VALUE_FMY: Specifications__Values__write_out_in_English(OUT, spec); return;
}
internal_error("no such family");
}
#line 476 "inform7/Chapter 16/Specifications.w"
void Specifications__log_concisely(specification *spec) {
log_specification_recursively(spec, FALSE);
STREAM_FLUSH(dl);
}
void Specifications__log_exhaustively(specification *spec) {
log_specification_recursively(spec, TRUE);
STREAM_FLUSH(dl);
}
#line 488 "inform7/Chapter 16/Specifications.w"
void log_specification_recursively(specification *spec, int details) {
if (spec == NULL) {
LOG("<null type>");
if (details) LOG("\n");
} else if ((((pointer_sized_int) spec) >= -1000) && (((pointer_sized_int) spec) <= 1000)) {
LOG("<corrupted? type %08x>", ((pointer_sized_int) spec));
if (details) LOG("\n");
} else {
int family = Specifications__get_family(spec), species = Specifications__get_species(spec);
if (Specifications__Taxa__exists(family) == FALSE) {
LOG("[Malformed:%d/%d]", family, species);
if (details) LOG("\n");
} else {
int w1 = spec->word_ref1, w2 = spec->word_ref2;
if (Specifications__is_generic(spec)) LOG("(G)"); else LOG("(A)");
if ((w1 >= 0) && (w2 >= w1) && (w2 < lexer_wordcount)) LOG("'$W'/", w1, w2);
if ((spec_test_ability(spec, DOCKET_SPCFLAG)) && (Specifications__Conditions__makes_callings(spec)))
LOG("c/");
LOG("$s/$s", family, species);
if (Specifications__get_kind(spec)) LOG("-$u", Specifications__get_kind(spec));
if (details) {
switch(family) {
case COMMAND_FMY: Specifications__Commands__log(spec); break;
case CONDITION_FMY: Specifications__Conditions__log(spec); break;
case MATCHING_FMY: Specifications__Matching__log(spec); break;
case STORAGE_FMY: Specifications__Storage__log(spec); break;
case VALUE_FMY: Specifications__Values__log(spec); break;
}
LOG("\n");
int i;
for (i=0; i<Specifications__get_argc(spec); i++) {
LOG("%d: ", i+1);
log_specification_recursively(Specifications__get_argument(spec, i), TRUE);
}
if (Specifications__has_invocation_list(spec))
Code__Invocations__Lists__log_in_detail(Specifications__invocation_list(spec));
}
}
}
}
#line 543 "inform7/Chapter 16/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(specification *spec1, specification *spec2, int *wont_mix) {
LOGIF(SPECIFICITIES, "Law %s (test %d): comparing $S with $S\n",
c_s_stage_law, cco++, spec1, spec2);
{
#line 584 "inform7/Chapter 16/Specifications.w"
if ((spec1 == NULL) && (spec2 != NULL)) return -1;
if ((spec1 != NULL) && (spec2 == NULL)) return 1;
if ((spec1 == NULL) && (spec2 == NULL)) return 0;
}
#line 550 "inform7/Chapter 16/Specifications.w"
;
int a = Specifications__species_is(spec1, DESCRIPTION_SPC),
b = Specifications__species_is(spec2, DESCRIPTION_SPC);
instance *I1 = Specifications__object_exactly_described_if_any(spec1);
instance *I2 = Specifications__object_exactly_described_if_any(spec2);
{
#line 594 "inform7/Chapter 16/Specifications.w"
int aa = Specifications__is_actual(spec1);
if ((a) && (I1 == NULL)) aa = FALSE;
int ba = Specifications__is_actual(spec2);
if ((b) && (I2 == NULL)) ba = FALSE;
if ((aa) && (!ba)) return 1;
if ((!aa) && (ba)) return -1;
}
#line 557 "inform7/Chapter 16/Specifications.w"
;
{
#line 605 "inform7/Chapter 16/Specifications.w"
if ((I1) && (I2 == NULL)) return 1;
if ((I1 == NULL) && (I2)) return -1;
}
#line 559 "inform7/Chapter 16/Specifications.w"
;
if (I1)
{
#line 616 "inform7/Chapter 16/Specifications.w"
LOGIF(SPECIFICITIES, "Test %d: Comparing specificity of instances $O and $O\n",
cco, I1, I2);
int pref = Config__Plugins__Call__more_specific(I1, I2);
if (pref != 0) return pref;
}
#line 560 "inform7/Chapter 16/Specifications.w"
;
if (wont_mix)
{
#line 624 "inform7/Chapter 16/Specifications.w"
int ev1 = ((a) || (Specifications__is_evaluating(spec1)));
int ev2 = ((b) || (Specifications__is_evaluating(spec2)));
if (Specifications__Storage__get_storage_form(spec1) == PROPERTY_VALUE_SPC) ev1 = FALSE;
if (Specifications__Storage__get_storage_form(spec2) == PROPERTY_VALUE_SPC) ev2 = FALSE;
if ((ev1) && (ev2)) {
int x = Specifications__Matching__can_we_match_value_descriptions(spec1, spec2);
int y = Specifications__Matching__can_we_match_value_descriptions(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 562 "inform7/Chapter 16/Specifications.w"
;
if ((a == TRUE) && (b == TRUE)) { /* case 1: both are descriptions */
return Specifications__Conditions__compare_specificity_of_DESCRIPTIONs(spec1, spec2);
} else if ((a == FALSE) && (b == FALSE)) { /* case 2: neither is a description */
{
#line 652 "inform7/Chapter 16/Specifications.w"
int t1 = Specifications__species_is(spec1, TABLE_ENTRY_SPC);
int t2 = Specifications__species_is(spec2, TABLE_ENTRY_SPC);
if ((t1 == TRUE) && (t2 == FALSE)) return 1;
if ((t1 == FALSE) && (t2 == TRUE)) return -1;
}
#line 567 "inform7/Chapter 16/Specifications.w"
;
} else { /* case 3: one is a description, the other isn't */
{
#line 666 "inform7/Chapter 16/Specifications.w"
if (I1) { if (a == TRUE) return 1; else return -1; }
else { if (a == TRUE) return -1; else return 1; }
}
#line 569 "inform7/Chapter 16/Specifications.w"
;
}
return 0;
}
#line 73 "inform7/Chapter 16/Text to Specifications.w"
#line 78 "inform7/Chapter 16/Text to Specifications.w"
expression_cache contextual_cache[NUMBER_OF_EXPCONS];
int parse_expression_called_before = FALSE;
#line 135 "inform7/Chapter 16/Text to Specifications.w"
void Specifications__warn_expression_cache(void) {
int i;
for (i=0; i<NUMBER_OF_EXPCONS; i++) {
contextual_cache[i].pe_cache_size = 0;
contextual_cache[i].pe_cache_posn = 0;
}
}
#line 147 "inform7/Chapter 16/Text to Specifications.w"
specification *parse_with_cache(int w1, int w2, int context) {
if ((w1 < 0) || (w2 < w1)) return Specifications__Unknown__new(-1, -1);
if ((context < 0) || (context >= NUMBER_OF_EXPCONS))
internal_error ("bad expression parsing context");
{
#line 86 "inform7/Chapter 16/Text to Specifications.w"
expression_cache *ec = &(contextual_cache[context]);
if (parse_expression_called_before == FALSE) {
Specifications__warn_expression_cache(); /* this empties all the caches */
parse_expression_called_before = TRUE;
}
int i;
for (i=0; i<ec->pe_cache_size; i++)
if ((w1 == ec->pe_cache[i].word_ref1) && (w2 == ec->pe_cache[i].word_ref2))
return ec->pe_cache[i].cached_pe_spec;
}
#line 152 "inform7/Chapter 16/Text to Specifications.w"
;
meaning_list *ml = NULL;
specification *spec = NULL;
int pc = PARSED_SPCONTEXT;
{
#line 175 "inform7/Chapter 16/Text to Specifications.w"
CLEAR_MLC_BACKTRACE;
switch(context) {
case VALUE_EXPCON:
if (parse_nt_against_word_range(s_value_NTM, w1, w2, NULL, NULL)) ml = most_recent_result_p;
spec = Parser__SP__Conversion__VAL_subtree_to_spec(ml);
break;
case CONDITION_EXPCON:
Code__LocalVariables__make_necessary_callings(w1, w2);
if (parse_nt_against_word_range(s_condition_NTM, w1, w2, NULL, NULL)) ml = most_recent_result_p;
spec = Parser__SP__Conversion__COND_subtree_to_spec(ml);
break;
case VOID_EXPCON:
if (parse_nt_against_word_range(s_command_NTM, w1, w2, NULL, NULL)) ml = most_recent_result_p;
spec = Parser__SP__Conversion__CMD_subtree_to_spec(ml);
break;
case TYPE_EXPCON:
if (parse_nt_against_word_range(s_type_expression_NTM, w1, w2, NULL, NULL)) ml = most_recent_result_p;
Problems__quote_words(9, w1, w2);
spec = Parser__SP__Conversion__TE_subtree_to_spec(ml);
pc = TYPE_PARSED_SPCONTEXT;
break;
case DESCRIPTIVE_TYPE_EXPCON:
if (parse_nt_against_word_range(s_descriptive_type_expression_NTM, w1, w2, NULL, NULL)) ml = most_recent_result_p;
Problems__quote_words(9, w1, w2);
spec = Parser__SP__Conversion__TE_subtree_to_spec(ml);
pc = TYPE_PARSED_SPCONTEXT;
break;
}
CLEAR_MLC_BACKTRACE;
}
#line 158 "inform7/Chapter 16/Text to Specifications.w"
;
if (spec->word_ref1 < 0) { spec->word_ref1 = w1; spec->word_ref2 = w2; }
{
#line 102 "inform7/Chapter 16/Text to Specifications.w"
expression_cache *ec = &(contextual_cache[context]);
ec->pe_cache[ec->pe_cache_posn].word_ref1 = w1;
ec->pe_cache[ec->pe_cache_posn].word_ref2 = w2;
ec->pe_cache[ec->pe_cache_posn].cached_pe_spec = 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 162 "inform7/Chapter 16/Text to Specifications.w"
;
if (!(Specifications__is_UNKNOWN(spec))) Specifications__Taxa__observe(spec, pc);
return spec;
}
#line 217 "inform7/Chapter 16/Text to Specifications.w"
int spec_value_NTMR(int w1, int w2, int *X, void **XP) {
#line 218 "inform7/Chapter 16/Text to Specifications.w"
specification *spec = parse_with_cache(w1, w2, VALUE_EXPCON);
if (Specifications__is_UNKNOWN(spec)) return FALSE;
*XP = spec;
return TRUE;
}
int spec_condition_NTMR(int w1, int w2, int *X, void **XP) {
#line 225 "inform7/Chapter 16/Text to Specifications.w"
specification *spec = parse_with_cache(w1, w2, CONDITION_EXPCON);
if (Specifications__is_UNKNOWN(spec)) return FALSE;
*XP = spec;
return TRUE;
}
int spec_command_NTMR(int w1, int w2, int *X, void **XP) {
#line 232 "inform7/Chapter 16/Text to Specifications.w"
specification *spec = parse_with_cache(w1, w2, VOID_EXPCON);
if (Specifications__is_UNKNOWN(spec)) return FALSE;
*XP = spec;
return TRUE;
}
int spec_type_expression_NTMR(int w1, int w2, int *X, void **XP) {
#line 239 "inform7/Chapter 16/Text to Specifications.w"
specification *spec = parse_with_cache(w1, w2, TYPE_EXPCON);
if (Specifications__is_UNKNOWN(spec)) return FALSE;
*XP = spec;
return TRUE;
}
int spec_descriptive_type_expression_NTMR(int w1, int w2, int *X, void **XP) {
#line 246 "inform7/Chapter 16/Text to Specifications.w"
specification *spec = parse_with_cache(w1, w2, DESCRIPTIVE_TYPE_EXPCON);
if (Specifications__is_UNKNOWN(spec)) return FALSE;
*XP = spec;
return TRUE;
}
#line 257 "inform7/Chapter 16/Text to Specifications.w"
int spec_type_expression_or_value_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 16/Text to Specifications.w"
#line 265 "inform7/Chapter 16/Text to Specifications.w"
int spec_global_variable_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 271 "inform7/Chapter 16/Text to Specifications.w"
*XP = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(
RETRIEVE_POINTER_nonlocal_variable(
Semantics__Nouns__ExcerptMeanings__data(
Parser__SP__MeaningLists__meaning(RP[1]))));
}
#line 266 "inform7/Chapter 16/Text to Specifications.w"
;
#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 16/Text to Specifications.w"
#line 279 "inform7/Chapter 16/Text to Specifications.w"
int spec_kind_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 285 "inform7/Chapter 16/Text to Specifications.w"
specification *spec = Specifications__Values__new_generic_CONSTANT(RP[1]);
spec->word_ref1 = w1; spec->word_ref2 = w2;
*XP = spec;
}
#line 280 "inform7/Chapter 16/Text to Specifications.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 281 "inform7/Chapter 16/Text to Specifications.w"
#line 293 "inform7/Chapter 16/Text to Specifications.w"
int spec_description_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1]; if (!(Specifications__species_is(RP[1], DESCRIPTION_SPC))) 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 295 "inform7/Chapter 16/Text to Specifications.w"
#line 299 "inform7/Chapter 16/Text to Specifications.w"
int spec_instance_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1]; if (!(Specifications__object_exactly_described_if_any(RP[1]))) 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 301 "inform7/Chapter 16/Text to Specifications.w"
#line 305 "inform7/Chapter 16/Text to Specifications.w"
int spec_table_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1]; if (!(Specifications__Values__is_CONSTANT_of_kind(RP[1], K_table))) 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 307 "inform7/Chapter 16/Text to Specifications.w"
#line 313 "inform7/Chapter 16/Text to Specifications.w"
int spec_stored_action_NTMR(int w1, int w2, int *X, void **XP) {
#line 314 "inform7/Chapter 16/Text to Specifications.w"
specification *S = NULL;
int p = permit_trying_omission;
permit_trying_omission = TRUE;
if (parse_nt_against_word_range(spec_condition_NTM, w1, w2, NULL, NULL)) S = most_recent_result_p;
permit_trying_omission = p;
if (S) {
if (Specifications__Values__is_actual_CONSTANT_of_kind(S, K_stored_action)) {
*XP = S; return TRUE;
} else if (Specifications__species_is(S, TEST_ACTION_SPC)) {
Plugins__Actions__coerce_TEST_ACTION_to_STORED_ACTION(S);
S->word_ref1 = w1; S->word_ref2 = w2;
*XP = S; return TRUE;
} else return FALSE;
}
return FALSE;
}
#line 27 "inform7/Chapter 16/Specification Versions of Other Structures.w"
specification *Specifications__new_generic_from_type_ID(int ID_number) {
if (ID_number == UNKNOWN) return Specifications__Unknown__new(-1, -1);
int family = UNKNOWN, species = UNKNOWN;
if (Specifications__Taxa__is_family_ID(ID_number)) {
family = ID_number;
species = UNKNOWN;
} else {
family = Specifications__Taxa__get_family_of_species(ID_number);
species = ID_number;
if (family == UNKNOWN) {
LOG("ID number is %d = $s\n", ID_number, ID_number);
internal_error("no permitted family for this species");
}
}
specification *spec = Specifications__new(family, species);
Specifications__make_generic(spec);
return spec;
}
#line 62 "inform7/Chapter 16/Specification Versions of Other Structures.w"
specification *Specifications__kind_as_spec(kind *K) {
if (K == NULL) return NULL;
return Specifications__Values__new_generic_CONSTANT(K);
}
#line 76 "inform7/Chapter 16/Specification Versions of Other Structures.w"
int Specifications__describes_an_object_vaguely_or_exactly(specification *spec) {
if (spec == NULL) return FALSE;
if (Specifications__species_is(spec, DESCRIPTION_SPC)) return TRUE;
if (Specifications__Values__is_CONSTANT_object(spec)) return TRUE;
return FALSE;
}
instance *Specifications__object_exactly_described_if_any(specification *spec) {
if (spec == NULL) return NULL;
if (Specifications__species_is(spec, DESCRIPTION_SPC)) return Specifications__Conditions__get_described_instance(spec);
if (Specifications__Values__is_actual_CONSTANT_object(spec)) {
if (Specifications__Values__is_nothing_object_constant(spec)) return NULL;
return instance_spec_to_instance(spec);
}
return NULL;
}
#line 85 "inform7/Chapter 16/Compiling from Specifications.w"
void Specifications__compile(OUTPUT_STREAM, specification *spec) {
LOGIF(EXPRESSIONS, "Compiling: $S\n", spec);
if (Specifications__is_generic(spec)) internal_error("compiled a generic specification");
spec = Data__NonlocalVariables__substitute_constants(spec);
LOG_INDENT;
specification breakable_copy = *spec;
spec_compile_primitive(OUT, &breakable_copy);
LOG_OUTDENT;
}
#line 99 "inform7/Chapter 16/Compiling from Specifications.w"
void spec_compile_primitive(OUTPUT_STREAM, specification *spec) {
Specifications__Taxa__observe(spec, COMPILED_SPCONTEXT);
kind *K_found = Specifications__evaluates_to(spec);
Kinds__notify_of_use(K_found);
char *suffix = "";
if (TEST_COMPILATION_MODE(DEREFERENCE_POINTERS_CMODE)) {
kind *K = Specifications__evaluates_to(spec);
if ((K) && (Kinds__uses_pointer_values(K))) {
WRITE("BlkValueCopy(");
Code__Frames__compile_allocation(OUT, K);
WRITE(", ");
suffix = ")";
}
}
switch(Specifications__get_family(spec)) {
case COMMAND_FMY: Specifications__Commands__compile(OUT, spec); break;
case CONDITION_FMY: Specifications__Conditions__compile(OUT, spec); break;
case MATCHING_FMY: Specifications__Matching__compile(OUT, spec); break;
case STORAGE_FMY: Specifications__Storage__compile(OUT, spec); break;
case UNKNOWN: break; /* for error recovery */
case VALUE_FMY: Specifications__Values__compile(OUT, spec); break;
}
WRITE("%s", suffix);
}
#line 130 "inform7/Chapter 16/Compiling from Specifications.w"
void Specifications__compile_to_kind(OUTPUT_STREAM, specification *value, kind *K_wanted) {
Kinds__notify_of_use(K_wanted);
kind *K_found = Specifications__evaluates_to(value);
Kinds__notify_of_use(K_found);
if ((Kinds__eq(K_wanted, K_understanding)) && (Kinds__eq(K_found, K_text))) {
Specifications__set_kind_of_value(value, K_understanding);
K_found = K_understanding;
}
int casting = Kinds__cast_call(OUT, K_found, K_wanted);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(PERMIT_LOCALS_IN_TEXT_CMODE);
Specifications__compile(OUT, value);
END_COMPILATION_MODE;
if (casting) WRITE(")");
}
#line 151 "inform7/Chapter 16/Compiling from Specifications.w"
void Specifications__compile_constant_to_kind(OUTPUT_STREAM, specification *value, kind *K_wanted) {
Kinds__notify_of_use(K_wanted);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
COMPILATION_MODE_ENTER(CONSTANT_CMODE);
Specifications__compile(OUT, Kinds__cast_constant(value, K_wanted));
END_COMPILATION_MODE;
}
#line 22 "inform7/Chapter 16/MATCHING Specifications.w"
void Specifications__Matching__create_species(void) {
Specifications__Taxa__set_source_name(MATCHING_FMY, "MATCHING_FMY");
Specifications__Taxa__permit_pair(MATCHING_FMY, NEW_LOCAL_VARIABLE_NAME_SPC,
PARSED_SPCONTEXT + TYPE_PARSED_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT + TYPE_FOUND_SPCONTEXT);
Specifications__Taxa__set_source_name(NEW_LOCAL_VARIABLE_NAME_SPC, "NEW_LOCAL_VARIABLE_NAME_SPC");
Specifications__Taxa__set_flag(NEW_LOCAL_VARIABLE_NAME_SPC, ASSOCIATED_KIND_SPCFLAG);
}
specification *Specifications__Matching__new_NEW_LOCAL_VARIABLE_NAME(kind *K) {
specification *spec = Specifications__new(MATCHING_FMY, NEW_LOCAL_VARIABLE_NAME_SPC);
if (K) Specifications__set_kind_of_value(spec, K);
Specifications__make_generic(spec);
return spec;
}
#line 42 "inform7/Chapter 16/MATCHING Specifications.w"
void Specifications__Matching__write_out_in_English(OUTPUT_STREAM, specification *spec) {
WRITE("a new name");
}
void Specifications__Matching__log(specification *spec) {
}
#line 54 "inform7/Chapter 16/MATCHING Specifications.w"
kind *Specifications__Matching__kind_when_evaluated(specification *spec) {
return NULL;
}
void Specifications__Matching__compile(OUTPUT_STREAM, specification *spec_found) {
internal_error("MATCHING specifications cannot be compiled");
}
#line 48 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__create_species(void) {
Specifications__Taxa__set_source_name(VALUE_FMY, "VALUE_FMY");
Specifications__Taxa__set_flag(VALUE_FMY, EVALUATING_SPCFLAG);
Specifications__Taxa__permit_pair(VALUE_FMY, CONSTANT_SPC,
TYPE_PARSED_SPCONTEXT + PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT +
TYPE_EXPECTED_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(CONSTANT_SPC, "CONSTANT_SPC");
Specifications__Taxa__set_flag(CONSTANT_SPC, ASSOCIATED_KIND_SPCFLAG);
Specifications__Taxa__set_flag(CONSTANT_SPC,
DOCKET_SPCFLAG + PROPOSITION_SPCFLAG); /* for |DESCRIPTION_SPC| constants only */
Specifications__Taxa__permit_pair(VALUE_FMY, PHRASE_TO_DECIDE_VALUE_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT +
COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(PHRASE_TO_DECIDE_VALUE_SPC, "PHRASE_TO_DECIDE_VALUE_SPC");
Specifications__Taxa__set_flag(PHRASE_TO_DECIDE_VALUE_SPC, PHRASAL_SPCFLAG + INVLIST_SPCFLAG);
}
#line 76 "inform7/Chapter 16/VALUE Specifications.w"
specification *Specifications__Values__new_actual_CONSTANT(kind *K) {
specification *spec = Specifications__new(VALUE_FMY, CONSTANT_SPC);
Specifications__set_kind_of_value(spec, K);
return spec;
}
specification *Specifications__Values__new_generic_CONSTANT(kind *K) {
specification *spec = Specifications__Values__new_actual_CONSTANT(K);
Specifications__make_generic(spec);
return spec;
}
#line 99 "inform7/Chapter 16/VALUE Specifications.w"
specification *Specifications__Values__new_self_object_constant(void) {
specification *spec = Specifications__Values__new_actual_CONSTANT(K_object);
Specifications__set_flag(spec, SELF_OBJECT_SPFLAG);
return spec;
}
specification *Specifications__Values__new_nothing_object_constant(void) {
specification *spec = Specifications__Values__new_actual_CONSTANT(K_object);
Specifications__set_flag(spec, NOTHING_OBJECT_SPFLAG);
return spec;
}
#line 115 "inform7/Chapter 16/VALUE Specifications.w"
specification *Specifications__Values__new_named_CONSTANT(instance *nc) {
return Data__Instances__get_value(nc);
}
instance *Specifications__Values__get_named_constant_if_any(specification *spec) {
if (Specifications__Values__is_actual_CONSTANT(spec)) {
kind *K = Specifications__get_kind(spec);
if (Kinds__is_an_enumeration(K))
return RETRIEVE_FROM_SPEC(spec, instance);
}
return NULL;
}
#line 132 "inform7/Chapter 16/VALUE Specifications.w"
specification *Specifications__Values__new_PHRASE_TO_DECIDE_VALUE(void) {
specification *spec = Specifications__new(VALUE_FMY, PHRASE_TO_DECIDE_VALUE_SPC);
Specifications__create_invocation_list(spec);
return spec;
}
#line 147 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__coerce_DESCRIPTION_to_VALUE(specification *spec, kind *K) {
if (Specifications__species_is(spec, DESCRIPTION_SPC) == FALSE)
internal_error("can't coerce non-DESCRIPTION");
pcalc_prop *prop = Specifications__get_proposition(spec);
if (prop) {
prop = Calculus__Propositions__copy(prop);
prop = Calculus__Propositions__trim_universal_quantifier(prop);
if (Calculus__Variables__number_free(prop) != 1) return FALSE;
Specifications__set_proposition(spec, prop);
}
Specifications__coerce_to(spec, VALUE_FMY, CONSTANT_SPC);
Specifications__set_kind_of_value(spec,
Kinds__unary_construction(CON_description, K));
return TRUE;
}
#line 169 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__coerce_UNDERSTANDING_to_TEXT(specification *spec) {
if (Specifications__species_is(spec, CONSTANT_SPC) == FALSE)
internal_error("can't coerce non-CONSTANT_SPC");
Specifications__set_kind_of_value(spec, K_text);
}
#line 178 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__coerce_NUMBER_to_REAL_NUMBER(specification *spec) {
if (Specifications__species_is(spec, CONSTANT_SPC) == FALSE)
internal_error("can't coerce non-CONSTANT_SPC");
Specifications__set_kind_of_value(spec, K_real_number);
}
#line 189 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_actual_CONSTANT(specification *spec) {
if ((Specifications__species_is(spec, CONSTANT_SPC)) && (Specifications__is_actual(spec))) return TRUE;
return FALSE;
}
int Specifications__Values__is_generic_CONSTANT(specification *spec) {
if ((Specifications__species_is(spec, CONSTANT_SPC)) && (Specifications__is_generic(spec))) return TRUE;
return FALSE;
}
#line 202 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_CONSTANT_object(specification *spec) {
if ((Specifications__species_is(spec, CONSTANT_SPC)) &&
(Kinds__le(Specifications__get_kind(spec), K_object)))
return TRUE;
return FALSE;
}
int Specifications__Values__is_CONSTANT_construction(specification *spec, kind_constructor *con) {
if ((Specifications__species_is(spec, CONSTANT_SPC)) &&
(Kinds__get_construct(Specifications__get_kind(spec)) == con))
return TRUE;
return FALSE;
}
int Specifications__Values__is_CONSTANT_of_kind(specification *spec, kind *K) {
if ((Specifications__species_is(spec, CONSTANT_SPC)) &&
(Kinds__eq(Specifications__get_kind(spec), K)))
return TRUE;
return FALSE;
}
int Specifications__Values__is_actual_CONSTANT_object(specification *spec) {
if ((Specifications__species_is(spec, CONSTANT_SPC)) &&
(Specifications__is_actual(spec)) &&
(Kinds__le(Specifications__get_kind(spec), K_object)))
return TRUE;
return FALSE;
}
int Specifications__Values__is_actual_CONSTANT_construction(specification *spec, kind_constructor *con) {
if ((Specifications__species_is(spec, CONSTANT_SPC)) && (Specifications__is_actual(spec)) &&
(Kinds__get_construct(Specifications__get_kind(spec)) == con))
return TRUE;
return FALSE;
}
int Specifications__Values__is_actual_CONSTANT_of_kind(specification *spec, kind *K) {
if ((Specifications__species_is(spec, CONSTANT_SPC)) && (Specifications__is_actual(spec)) &&
(Kinds__eq(Specifications__get_kind(spec), K))) return TRUE;
return FALSE;
}
int Specifications__Values__is_generic_CONSTANT_of_kind(specification *spec, kind *K) {
if ((Specifications__species_is(spec, CONSTANT_SPC)) && (Specifications__is_generic(spec)) &&
(Kinds__eq(Specifications__get_kind(spec), K))) return TRUE;
return FALSE;
}
int Specifications__Values__is_generic_CONSTANT_construction(specification *spec, kind_constructor *con) {
if ((Specifications__species_is(spec, CONSTANT_SPC)) && (Specifications__is_generic(spec)) &&
(Kinds__get_construct(Specifications__get_kind(spec)) == con))
return TRUE;
return FALSE;
}
#line 261 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__is_nothing_object_constant(specification *spec) {
if (Specifications__test_flag(spec, NOTHING_OBJECT_SPFLAG)) return TRUE;
return FALSE;
}
int Specifications__Values__is_self_object_constant(specification *spec) {
if (Specifications__test_flag(spec, SELF_OBJECT_SPFLAG)) return TRUE;
return FALSE;
}
instance *Specifications__Values__instance_of_CONSTANT_object_if_any(specification *spec) {
if (Specifications__Values__is_actual_CONSTANT_object(spec)) {
if (Specifications__test_flag(spec, SELF_OBJECT_SPFLAG)) return NULL;
if (Specifications__test_flag(spec, NOTHING_OBJECT_SPFLAG)) return NULL;
return instance_spec_to_instance(spec);
}
return NULL;
}
#line 284 "inform7/Chapter 16/VALUE Specifications.w"
property *Specifications__Values__get_property_name_if_any(specification *spec) {
if (Specifications__Values__is_actual_CONSTANT_construction(spec, CON_property))
return Properties__from_specification(spec);
return NULL;
}
#line 295 "inform7/Chapter 16/VALUE Specifications.w"
specification *Specifications__Values__new_integer_literal(int n) {
single_integer *sint = Memory__SingleIntegers__new(n);
specification *spec = Specifications__Values__new_actual_CONSTANT(K_number);
Specifications__set_flag(spec, EXPLICIT_LITERAL_SPFLAG);
Specifications__set_structure_field(spec, STORE_POINTER_single_integer(sint));
return spec;
}
#line 309 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__get_literal_value(specification *spec) {
if (spec == NULL) return 0;
if (Specifications__test_flag(spec, EXPLICIT_LITERAL_SPFLAG)) {
single_integer *sint =
RETRIEVE_POINTER_single_integer(Specifications__get_structure_field(spec));
return Memory__SingleIntegers__get(sint);
}
if (spec->word_ref1 < 0)
internal_error("Text no longer available for CONSTANT compilation");
if (Specifications__Values__is_actual_CONSTANT_of_kind(spec, K_real_number)) {
if (parse_nt_against_word_range(literal_real_number_NTM, spec->word_ref1, spec->word_ref2, NULL, NULL) == FALSE)
internal_error("Parsing anomaly for CONSTANT compilation");
} else {
if (parse_nt_against_word_range(literal_NTM, spec->word_ref1, spec->word_ref2, NULL, NULL) == FALSE)
internal_error("Parsing anomaly for CONSTANT compilation");
}
return most_recent_result;
}
#line 332 "inform7/Chapter 16/VALUE Specifications.w"
specification *Specifications__Values__new_text_literal(char *x) {
int x1 = lexer_wordcount;
Text__feed_into_lexer(x, FALSE, NULL);
Text__feed_into_lexer(" ", FALSE, NULL);
specification *spec = Specifications__Values__new_actual_CONSTANT(K_text);
spec->word_ref1 = x1; spec->word_ref2 = x1;
return spec;
}
specification *Specifications__Values__new_text_literal_from_stream(STREAM *S) {
specification *spec = Specifications__Values__new_text_literal(STREAM_TEXT(S));
Specifications__set_data(spec, TEXT_UNESCAPED_SPDATA, 1);
return spec;
}
specification *Specifications__Values__faux_text_literal_from_stream(STREAM *S) {
specification *spec = Specifications__Values__new_actual_CONSTANT(K_text);
Specifications__set_flag(spec, EXPLICIT_LITERAL_SPFLAG);
Specifications__set_structure_field(spec, STORE_POINTER_STREAM(S));
return spec;
}
#line 357 "inform7/Chapter 16/VALUE Specifications.w"
specification *Specifications__Values__new_pair_combination(specification *X, specification *Y) {
kind *kX = Specifications__evaluates_to(X);
kind *kY = Specifications__evaluates_to(Y);
kind *K = Kinds__pair_kind(kX, kY);
specification *spec = Specifications__Values__new_actual_CONSTANT(K);
combinator *comb_X = CREATE(combinator);
comb_X->combination_item = X;
combinator *comb_Y = CREATE(combinator);
comb_Y->combination_item = Y;
comb_X->next = comb_Y; comb_Y->next = NULL;
Specifications__set_structure_field(spec, STORE_POINTER_combinator(comb_X));
return spec;
}
void Specifications__Values__extract_pair(specification *pair, specification **X, specification **Y) {
combinator *comb = RETRIEVE_POINTER_combinator(Specifications__get_structure_field(pair));
*X = comb->combination_item;
*Y = comb->next->combination_item;
}
#line 410 "inform7/Chapter 16/VALUE Specifications.w"
int Specifications__Values__compare_CONSTANT(specification *spec1, specification *spec2) {
if (Specifications__Values__is_actual_CONSTANT(spec1) == FALSE) return FALSE;
if (Specifications__Values__is_actual_CONSTANT(spec2) == FALSE) return FALSE;
kind *K1 = Specifications__get_kind(spec1);
kind *K2 = Specifications__get_kind(spec2);
if ((Kinds__le(K1, K2) == FALSE) &&
(Kinds__le(K2, K1) == FALSE)) return FALSE;
if (Kinds__eq(K1, K_text)) {
if (spec1->word_ref1 == spec2->word_ref1) return TRUE;
if ((spec1->word_ref1 >= 0) &&
(spec2->word_ref1 >= 0)) {
char *p1 = Text__word_raw_text(spec1->word_ref1);
char *p2 = Text__word_raw_text(spec2->word_ref1);
if (strcmp(p1, p2) == 0) return TRUE;
}
return FALSE;
}
switch (Kinds__get_constant_compilation_method(K1)) {
case LITERAL_CCM: {
int v1, v2;
parse_nt_against_word_range(literal_NTM, spec1->word_ref1, spec1->word_ref2, NULL, NULL);
v1 = most_recent_result;
parse_nt_against_word_range(literal_NTM, spec2->word_ref1, spec2->word_ref2, NULL, NULL);
v2 = most_recent_result;
if (v1 == v2) return TRUE;
return FALSE;
}
case NAMED_CONSTANT_CCM: {
instance *I1 = Specifications__Values__get_named_constant_if_any(spec1);
instance *I2 = Specifications__Values__get_named_constant_if_any(spec2);
if (I1 == I2) return TRUE;
return FALSE;
}
case SPECIAL_CCM: {
COMPARE_CONSTANTS_USING(CON_activity, activity, Code__Activities__from_specification)
KKCOMPARE_CONSTANTS_USING(object, instance, Specifications__Values__instance_of_CONSTANT_object_if_any)
COMPARE_CONSTANTS_USING(CON_phrase, constant_phrase, MAP_spec_to_constant_phrase)
COMPARE_CONSTANTS_USING(CON_property, property, Properties__from_specification)
COMPARE_CONSTANTS_USING(CON_rule, rule, Code__Rules__from_specification)
COMPARE_CONSTANTS_USING(CON_rulebook, rulebook, Code__Rulebooks__from_specification)
COMPARE_CONSTANTS_USING(CON_table_column, table_column, Data__Tables__Columns__from_specification)
KCOMPARE_CONSTANTS(action_name, action_name)
KCOMPARE_CONSTANTS(equation, equation)
COMPARE_CONSTANTS_USING(CON_relation, binary_predicate, RELATION_spec_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 467 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__write_out_in_English(OUTPUT_STREAM, specification *spec) {
switch (Specifications__get_species(spec)) {
case PHRASE_TO_DECIDE_VALUE_SPC: {
kind *dtr = Specifications__evaluates_to(spec);
WRITE("an instruction to work out ");
Kinds__Textual__write_articled(OUT, dtr);
break;
}
case CONSTANT_SPC: {
if (Specifications__Values__is_generic_CONSTANT(spec)) {
Kinds__Textual__write_articled(OUT, Specifications__get_kind(spec));
return;
}
int w1 = spec->word_ref1, w2 = spec->word_ref2;
if (Specifications__Values__is_CONSTANT_construction(spec, CON_property)) {
if (w1 > 0) Text__print_raw_text_to_stream(w1, w2, OUT);
else WRITE("the name of a property");
return;
}
Text__print_raw_text_to_stream(w1, w2, OUT);
break;
}
}
}
#line 495 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__log(specification *spec) {
switch (Specifications__get_species(spec)) {
case CONSTANT_SPC: {
instance *I = Specifications__Values__get_named_constant_if_any(spec);
if (I)
if (Data__Instances__identifier(I))
LOG("(%s)", Data__Instances__identifier(I));
if (Specifications__Values__is_actual_CONSTANT_object(spec)) {
if (Specifications__test_flag(spec, SELF_OBJECT_SPFLAG)) LOG("(-self-)");
else if (Specifications__test_flag(spec, NOTHING_OBJECT_SPFLAG)) LOG("(-nothing-)");
else LOG("($O)", instance_spec_to_instance(spec));
}
}
}
}
#line 516 "inform7/Chapter 16/VALUE Specifications.w"
kind *Specifications__Values__kind_when_VALUE_is_evaluated(specification *spec) {
if (spec == NULL) internal_error("Specifications__Values__kind_when_VALUE_is_evaluated on NULL");
switch (Specifications__get_species(spec)) {
case CONSTANT_SPC:
if (Specifications__Values__is_actual_CONSTANT_object(spec))
{
#line 541 "inform7/Chapter 16/VALUE Specifications.w"
if (Specifications__test_flag(spec, SELF_OBJECT_SPFLAG)) return K_object;
else if (Specifications__test_flag(spec, NOTHING_OBJECT_SPFLAG)) return K_object;
else {
instance *I = instance_spec_to_instance(spec);
if (I) return Data__Instances__kind(I);
}
}
#line 521 "inform7/Chapter 16/VALUE Specifications.w"
;
if (Specifications__Values__is_actual_CONSTANT_construction(spec, CON_relation))
{
#line 551 "inform7/Chapter 16/VALUE Specifications.w"
binary_predicate *bp = RELATION_spec_to_binary_predicate(spec);
return Semantics__BPs__kind(bp);
}
#line 523 "inform7/Chapter 16/VALUE Specifications.w"
;
if (Specifications__Values__is_actual_CONSTANT_construction(spec, CON_phrase))
{
#line 563 "inform7/Chapter 16/VALUE Specifications.w"
return Code__Phrases__Constants__kind(MAP_spec_to_constant_phrase(spec));
}
#line 525 "inform7/Chapter 16/VALUE Specifications.w"
;
if (Specifications__Values__is_actual_CONSTANT_construction(spec, CON_list_of))
{
#line 557 "inform7/Chapter 16/VALUE Specifications.w"
return Data__Lists__kind_of_list_at(spec->word_ref1);
}
#line 527 "inform7/Chapter 16/VALUE Specifications.w"
;
return Specifications__get_kind(spec);
case PHRASE_TO_DECIDE_VALUE_SPC:
{
#line 590 "inform7/Chapter 16/VALUE Specifications.w"
invocation *deciding_inv = NULL, *first_inv = NULL;
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_INVOCATION_LIST(inv, Specifications__invocation_list(spec)) {
if (first_inv == NULL) first_inv = inv;
if (Code__Invocations__test_flag(inv, PASSED_INVFLAG)) { deciding_inv = inv; break; }
}
if (deciding_inv == NULL) deciding_inv = first_inv;
if (deciding_inv) {
phrase *ph = deciding_inv->phrase_invoked;
if ((ph) && (Code__Phrases__TypeData__get_mor(&(ph->type_data)) == DECIDES_VALUE_MOR)) {
if (Code__Phrases__TypeData__return_decided_dimensionally(&(ph->type_data))) {
if (deciding_inv->kind_resulting) return deciding_inv->kind_resulting;
return K_value;
} else {
if (deciding_inv->kind_resulting) return deciding_inv->kind_resulting;
kind *K = Code__Phrases__TypeData__get_return_kind(&(ph->type_data));
if (Kinds__definite(K) == FALSE) return K_value;
return K;
}
}
}
return NULL;
}
#line 530 "inform7/Chapter 16/VALUE Specifications.w"
;
}
internal_error("unknown evaluating VALUE type"); return NULL;
}
#line 616 "inform7/Chapter 16/VALUE Specifications.w"
void Specifications__Values__compile(OUTPUT_STREAM, specification *spec_found) {
switch(Specifications__get_species(spec_found)) {
case PHRASE_TO_DECIDE_VALUE_SPC:
Code__Invocations__Compiler__compile(OUT,
Specifications__invocation_list(spec_found), spec_found->word_ref1);
return;
case CONSTANT_SPC: {
kind *kind_of_constant = Specifications__get_kind(spec_found);
int ccm = Kinds__get_constant_compilation_method(kind_of_constant);
switch(ccm) {
case NONE_CCM: /* constant values of this kind cannot exist */
LOG("SP: $S; kind: $u\n", spec_found, kind_of_constant);
internal_error("Tried to compile CONSTANT SP for a disallowed kind");
return;
case LITERAL_CCM:
{
#line 645 "inform7/Chapter 16/VALUE Specifications.w"
WRITE("%d", Specifications__Values__get_literal_value(spec_found));
}
#line 630 "inform7/Chapter 16/VALUE Specifications.w"
; return;
case NAMED_CONSTANT_CCM:
{
#line 650 "inform7/Chapter 16/VALUE Specifications.w"
instance *I = RETRIEVE_FROM_SPEC(spec_found, instance);
WRITE("%s", Data__Instances__identifier(I));
}
#line 631 "inform7/Chapter 16/VALUE Specifications.w"
; return;
case SPECIAL_CCM:
{
#line 657 "inform7/Chapter 16/VALUE Specifications.w"
if (Config__Plugins__Call__compile_constant(OUT, kind_of_constant, spec_found))
return;
if (Kinds__get_construct(kind_of_constant) == CON_activity) {
activity *act = Code__Activities__from_specification(spec_found);
WRITE("%s", Code__Activities__identifier(act));
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_combination) {
combinator *comb = COMBINATION_spec_to_combinator(spec_found);
while (comb) {
Specifications__compile(OUT, comb->combination_item);
comb = comb->next;
if (comb) WRITE(", ");
}
return;
}
if (Kinds__eq(kind_of_constant, K_equation)) {
equation *eqn = equation_spec_to_equation(spec_found);
WRITE("%s", Data__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) {
Data__Lists__compile_literal_list(OUT, spec_found->word_ref1);
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_phrase) {
constant_phrase *cphr = MAP_spec_to_constant_phrase(spec_found);
Code__Phrases__Constants__compile(OUT, cphr);
return;
}
if (Kinds__le(kind_of_constant, K_object)) {
if (Specifications__test_flag(spec_found, SELF_OBJECT_SPFLAG)) WRITE("self");
else if (Specifications__test_flag(spec_found, NOTHING_OBJECT_SPFLAG)) WRITE("nothing");
else {
instance *I = instance_spec_to_instance(spec_found);
WRITE("%s", Data__Instances__identifier(I));
parse_node *NB = Code__Routines__code_line();
if (NB) Data__Instances__note_usage(I, NB);
}
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_property) {
{
#line 782 "inform7/Chapter 16/VALUE Specifications.w"
int parity = 1;
if (parse_nt_against_word_range(negated_clause_NTM, spec_found->word_ref1, spec_found->word_ref2, NULL, NULL)) parity = -1;
property *prn = Properties__from_specification(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 704 "inform7/Chapter 16/VALUE Specifications.w"
;
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_relation) {
binary_predicate *bp = RELATION_spec_to_binary_predicate(spec_found);
WRITE("Rel_Record_%d", bp->allocation_id);
Semantics__BPs__mark_as_needed(bp);
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_rule) {
rule *R = Code__Rules__from_specification(spec_found);
Code__Rules__compile(OUT, R);
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_rulebook) {
rulebook *rb = Code__Rulebooks__from_specification(spec_found);
WRITE("%d", rb->allocation_id);
return;
}
if (Kinds__eq(kind_of_constant, K_rulebook_outcome)) {
named_rulebook_outcome *rbno =
rulebook_outcome_spec_to_named_rulebook_outcome(spec_found);
WRITE("RBNO_%d", rbno->allocation_id);
return;
}
if (Kinds__eq(kind_of_constant, K_table)) {
table *t = table_spec_to_table(spec_found);
WRITE("%s", Data__Tables__identifier(t));
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_table_column) {
table_column *tc = Data__Tables__Columns__from_specification(spec_found);
WRITE("%d", Data__Tables__Columns__get_id(tc));
return;
}
if (Kinds__eq(kind_of_constant, K_text)) {
Data__Strings__compile_general(OUT, spec_found);
return;
}
if (Kinds__eq(kind_of_constant, K_understanding)) {
if (spec_found->word_ref1 < 0)
internal_error("Text no longer available for CONSTANT/UNDERSTANDING");
Plugins__Parsing__compile_understanding(OUT,
spec_found->word_ref1, spec_found->word_ref2, FALSE);
return;
}
if (Kinds__eq(kind_of_constant, K_use_option)) {
use_option *uo = use_option_spec_to_use_option(spec_found);
WRITE("%d", uo->allocation_id);
return;
}
if (Kinds__eq(kind_of_constant, K_verb)) {
verb_conjugation *vc = verb_spec_to_verb_conjugation(spec_found);
WRITE("ConjugateVerb_%d", vc->allocation_id);
return;
}
if (Kinds__eq(kind_of_constant, K_response)) {
rule *R = Code__Rules__from_specification(spec_found);
int c = Specifications__get_data(spec_found, RESPONSE_CODE_SPDATA);
Data__Strings__compile_response_constant(OUT, R, c);
Code__Rules__now_rule_needs_response(R, c, -1);
return;
}
LOG("Kov is $u\n", kind_of_constant);
internal_error("no special ccm provided");
}
#line 632 "inform7/Chapter 16/VALUE Specifications.w"
; return;
}
}
}
}
#line 67 "inform7/Chapter 16/STORAGE Specifications.w"
int storage_nonkind_types_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 78 "inform7/Chapter 16/STORAGE Specifications.w"
#line 82 "inform7/Chapter 16/STORAGE Specifications.w"
void Specifications__Storage__create_species(void) {
Specifications__Taxa__set_source_name(STORAGE_FMY, "STORAGE_FMY");
Specifications__Taxa__set_flag(STORAGE_FMY, EVALUATING_SPCFLAG);
Specifications__Taxa__set_parsing_names(STORAGE_FMY,
Text__Languages__word(storage_nonkind_types_NTM, 0),
Text__Languages__word(storage_nonkind_types_NTM, 1));
Specifications__Taxa__permit_pair(STORAGE_FMY, UNKNOWN,
TYPE_PARSED_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT);
Specifications__Taxa__permit_pair(STORAGE_FMY, LOCAL_VARIABLE_SPC,
TYPE_PARSED_SPCONTEXT + PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT +
TYPE_EXPECTED_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_parsing_names(LOCAL_VARIABLE_SPC,
Text__Languages__word(storage_nonkind_types_NTM, 2),
Text__Languages__word(storage_nonkind_types_NTM, 3));
Specifications__Taxa__set_source_name(LOCAL_VARIABLE_SPC, "LOCAL_VARIABLE_SPC");
Specifications__Taxa__set_flag(LOCAL_VARIABLE_SPC, ASSOCIATED_KIND_SPCFLAG);
Specifications__Taxa__permit_pair(STORAGE_FMY, NONLOCAL_VARIABLE_SPC,
TYPE_PARSED_SPCONTEXT + PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT +
TYPE_EXPECTED_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(NONLOCAL_VARIABLE_SPC, "NONLOCAL_VARIABLE_SPC");
Specifications__Taxa__set_flag(NONLOCAL_VARIABLE_SPC, ASSOCIATED_KIND_SPCFLAG);
Specifications__Taxa__permit_pair(STORAGE_FMY, PROPERTY_VALUE_SPC,
PARSED_SPCONTEXT + TYPE_PARSED_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT +
TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(PROPERTY_VALUE_SPC, "PROPERTY_VALUE_SPC");
Specifications__Taxa__set_parsing_names(PROPERTY_VALUE_SPC,
Text__Languages__word(storage_nonkind_types_NTM, 4),
Text__Languages__word(storage_nonkind_types_NTM, 5));
Specifications__Taxa__set_flag(PROPERTY_VALUE_SPC, ARGUMENTS_SPCFLAG);
Specifications__Taxa__permit_pair(STORAGE_FMY, TABLE_ENTRY_SPC,
TYPE_PARSED_SPCONTEXT + PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT +
TYPE_EXPECTED_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_parsing_names(TABLE_ENTRY_SPC,
Text__Languages__word(storage_nonkind_types_NTM, 6),
Text__Languages__word(storage_nonkind_types_NTM, 7));
Specifications__Taxa__set_source_name(TABLE_ENTRY_SPC, "TABLE_ENTRY_SPC");
Specifications__Taxa__set_flag(TABLE_ENTRY_SPC, ARGUMENTS_SPCFLAG);
Specifications__Taxa__permit_pair(STORAGE_FMY, LIST_ENTRY_SPC,
TYPE_PARSED_SPCONTEXT + PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT +
TYPE_EXPECTED_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_parsing_names(LIST_ENTRY_SPC,
Text__Languages__word(storage_nonkind_types_NTM, 8),
Text__Languages__word(storage_nonkind_types_NTM, 9));
Specifications__Taxa__set_source_name(LIST_ENTRY_SPC, "LIST_ENTRY_SPC");
Specifications__Taxa__set_flag(LIST_ENTRY_SPC, ARGUMENTS_SPCFLAG);
}
#line 137 "inform7/Chapter 16/STORAGE Specifications.w"
specification *Specifications__Storage__new_LOCAL_VARIABLE(int w1, int w2, local_variable *lvar) {
specification *spec = Specifications__new(STORAGE_FMY, LOCAL_VARIABLE_SPC);
spec->word_ref1 = w1; spec->word_ref2 = w2;
ATTACH_TO_SPEC(spec, local_variable, lvar);
if (lvar == NULL) internal_error("bad local variable");
return spec;
}
specification *Specifications__Storage__new_generic_LOCAL_VARIABLE(kind *K) {
specification *spec = Specifications__new(STORAGE_FMY, LOCAL_VARIABLE_SPC);
Specifications__make_generic(spec);
Specifications__set_kind_of_value(spec, K);
ATTACH_TO_SPEC(spec, local_variable, NULL);
return spec;
}
specification *Specifications__Storage__new_actual_NONLOCAL_VARIABLE(nonlocal_variable *nlv) {
specification *spec = Specifications__new(STORAGE_FMY, NONLOCAL_VARIABLE_SPC);
ATTACH_TO_SPEC(spec, nonlocal_variable, nlv);
spec->word_ref1 = nlv->word_ref1;
spec->word_ref2 = nlv->word_ref2;
return spec;
}
specification *Specifications__Storage__new_generic_NONLOCAL_VARIABLE(kind *K) {
specification *spec = Specifications__new(STORAGE_FMY, NONLOCAL_VARIABLE_SPC);
Specifications__make_generic(spec);
Specifications__set_kind_of_value(spec, K);
return spec;
}
#line 172 "inform7/Chapter 16/STORAGE Specifications.w"
specification *Specifications__Storage__new_TABLE_ENTRY(void) {
specification *spec = Specifications__new(STORAGE_FMY, TABLE_ENTRY_SPC);
return spec;
}
#line 180 "inform7/Chapter 16/STORAGE Specifications.w"
specification *Specifications__Storage__new_LIST_ENTRY(specification *owner, specification *index) {
specification *spec = Specifications__new(STORAGE_FMY, LIST_ENTRY_SPC);
Specifications__set_argument(spec, 0, owner);
Specifications__set_argument(spec, 1, index);
return spec;
}
#line 196 "inform7/Chapter 16/STORAGE Specifications.w"
specification *Specifications__Storage__new_PROPERTY_VALUE(specification *prop, specification *owner) {
specification *spec = Specifications__new(STORAGE_FMY, PROPERTY_VALUE_SPC);
Specifications__set_argument(spec, 0, prop);
Specifications__set_argument(spec, 1, owner);
if ((prop->word_ref1 >= 0) && (owner->word_ref1 >= 0)) {
spec->word_ref1 = prop->word_ref1;
if (spec->word_ref1 > owner->word_ref1) spec->word_ref1 = owner->word_ref1;
spec->word_ref2 = prop->word_ref2;
if (spec->word_ref2 < owner->word_ref2) spec->word_ref2 = owner->word_ref2;
} else if (prop->word_ref1 >= 0) {
spec->word_ref1 = prop->word_ref1;
spec->word_ref2 = prop->word_ref2;
}
return spec;
}
#line 216 "inform7/Chapter 16/STORAGE Specifications.w"
specification *Specifications__Storage__underlying_property(specification *spec) {
if (Specifications__species_is(spec, PROPERTY_VALUE_SPC)) {
if (Specifications__Values__is_self_object_constant(Specifications__get_argument(spec, 1)))
return Specifications__get_argument(spec, 0);
return spec;
}
internal_error("no underlying property"); return NULL;
}
#line 228 "inform7/Chapter 16/STORAGE Specifications.w"
int Specifications__Storage__get_storage_form(specification *spec) {
if (Specifications__family_is(spec, STORAGE_FMY)) return Specifications__get_species(spec);
return UNKNOWN;
}
int Specifications__Storage__is_generic(specification *spec) {
if ((Specifications__family_is(spec, STORAGE_FMY)) && (Specifications__is_generic(spec)) &&
(Specifications__species_is(spec, UNKNOWN))) return TRUE;
return FALSE;
}
#line 242 "inform7/Chapter 16/STORAGE Specifications.w"
int Specifications__Storage__is_actual_NONLOCAL_VARIABLE(specification *spec) {
if ((Specifications__species_is(spec, NONLOCAL_VARIABLE_SPC)) && (Specifications__is_actual(spec))) return TRUE;
return FALSE;
}
nonlocal_variable *Specifications__Storage__get_nonlocal_variable_if_any(specification *spec) {
if ((Specifications__species_is(spec, NONLOCAL_VARIABLE_SPC)) && (Specifications__is_actual(spec)))
return RETRIEVE_FROM_SPEC(spec, nonlocal_variable);
return NULL;
}
int Specifications__Storage__is_constant_NONLOCAL_VARIABLE(specification *spec) {
nonlocal_variable *nlv = Specifications__Storage__get_nonlocal_variable_if_any(spec);
if (nlv) return Data__NonlocalVariables__is_constant(nlv);
return FALSE;
}
int Specifications__Storage__is_generic_NONLOCAL_VARIABLE(specification *spec) {
if ((Specifications__species_is(spec, NONLOCAL_VARIABLE_SPC)) && (Specifications__is_generic(spec))) return TRUE;
return FALSE;
}
#line 268 "inform7/Chapter 16/STORAGE Specifications.w"
int Specifications__Storage__is_global_variable(specification *spec) {
if (Specifications__Storage__get_nonlocal_variable_if_any(spec)) return TRUE;
return FALSE;
}
#line 276 "inform7/Chapter 16/STORAGE Specifications.w"
void Specifications__Storage__write_out_in_English(OUTPUT_STREAM, specification *spec) {
switch(Specifications__get_species(spec)) {
case LOCAL_VARIABLE_SPC: WRITE("a temporary named value"); break;
case NONLOCAL_VARIABLE_SPC:
if (Specifications__get_kind(spec)) {
Kinds__Textual__write_articled(OUT, Specifications__get_kind(spec));
WRITE(" that varies");
} else WRITE("a non-temporary variable");
break;
case TABLE_ENTRY_SPC: WRITE("a table entry"); break;
case LIST_ENTRY_SPC: WRITE("a list entry"); break;
case PROPERTY_VALUE_SPC:
if ((Specifications__get_argc(spec) == 2) &&
(Specifications__Values__is_CONSTANT_construction(Specifications__get_argument(spec, 0), CON_property))) {
property *prn = Specifications__Values__get_property_name_if_any(
Specifications__get_argument(spec, 0));
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 303 "inform7/Chapter 16/STORAGE Specifications.w"
void Specifications__Storage__log(specification *spec) {
switch (Specifications__get_species(spec)) {
case LOCAL_VARIABLE_SPC: {
local_variable *lvar = RETRIEVE_FROM_SPEC(spec, local_variable);
if (lvar == NULL) LOG("(existing)");
else LOG("(%s;$u)",
Code__LocalVariables__lvalue(lvar),
Code__LocalVariables__unproblematic_kind(lvar));
break;
}
case NONLOCAL_VARIABLE_SPC:
if (Specifications__is_actual(spec)) {
nonlocal_variable *q = RETRIEVE_FROM_SPEC(spec, nonlocal_variable);
LOG("($Z)", q);
}
break;
}
}
#line 325 "inform7/Chapter 16/STORAGE Specifications.w"
kind *Specifications__Storage__kind_when_STORAGE_is_evaluated(specification *spec) {
if (spec == NULL) internal_error("Specifications__Values__kind_when_VALUE_is_evaluated on NULL");
switch (Specifications__get_species(spec)) {
case LOCAL_VARIABLE_SPC:
{
#line 340 "inform7/Chapter 16/STORAGE Specifications.w"
local_variable *lvar = RETRIEVE_FROM_SPEC(spec, local_variable);
if (lvar == NULL) return K_value; /* for "existing" */
return Code__LocalVariables__unproblematic_kind(lvar);
}
#line 328 "inform7/Chapter 16/STORAGE Specifications.w"
;
case NONLOCAL_VARIABLE_SPC:
{
#line 347 "inform7/Chapter 16/STORAGE Specifications.w"
if (Specifications__is_generic(spec)) return K_value;
nonlocal_variable *nlv = RETRIEVE_FROM_SPEC(spec, nonlocal_variable);
return Data__NonlocalVariables__kind(nlv);
}
#line 329 "inform7/Chapter 16/STORAGE Specifications.w"
;
case TABLE_ENTRY_SPC:
{
#line 355 "inform7/Chapter 16/STORAGE Specifications.w"
if (Specifications__get_argc(spec) > 0) { /* i.e., always, for actual table entry specifications */
specification *fts = Specifications__get_argument(spec, 0);
table_column *tc = Data__Tables__Columns__from_specification(fts);
return Data__Tables__Columns__get_kind(tc);
}
return NULL; /* can happen when scanning phrase arguments, which are generic */
}
#line 330 "inform7/Chapter 16/STORAGE Specifications.w"
;
case LIST_ENTRY_SPC:
{
#line 365 "inform7/Chapter 16/STORAGE Specifications.w"
if (Specifications__get_argc(spec) == 2) { /* i.e., always, for actual list entry specifications */
kind *K1 = Specifications__evaluates_to(Specifications__get_argument(spec, 0));
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 331 "inform7/Chapter 16/STORAGE Specifications.w"
;
case PROPERTY_VALUE_SPC:
{
#line 375 "inform7/Chapter 16/STORAGE Specifications.w"
if (Specifications__get_argc(spec) == 2) {
property *prn = Specifications__Values__get_property_name_if_any(Specifications__get_argument(spec, 0));
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 332 "inform7/Chapter 16/STORAGE Specifications.w"
;
}
return K_value; /* a generic answer for storage of an unknown sort */
}
#line 385 "inform7/Chapter 16/STORAGE Specifications.w"
local_variable *Specifications__Storage__get_local_variable_if_any(specification *spec) {
if (Specifications__species_is(spec, LOCAL_VARIABLE_SPC))
return RETRIEVE_FROM_SPEC(spec, local_variable);
return NULL;
}
#line 396 "inform7/Chapter 16/STORAGE Specifications.w"
void Specifications__Storage__compile(OUTPUT_STREAM, specification *spec_found) {
switch (Specifications__get_species(spec_found)) {
case LOCAL_VARIABLE_SPC:
{
#line 411 "inform7/Chapter 16/STORAGE Specifications.w"
local_variable *lvar = RETRIEVE_FROM_SPEC(spec_found, local_variable);
if (lvar == NULL) {
LOG("Bad: %08x\n", spec_found);
internal_error("Compiled never-specified LOCAL VARIABLE SP");
}
WRITE("%s", Code__LocalVariables__lvalue(lvar));
return;
}
#line 398 "inform7/Chapter 16/STORAGE Specifications.w"
;
case NONLOCAL_VARIABLE_SPC:
{
#line 422 "inform7/Chapter 16/STORAGE Specifications.w"
nonlocal_variable *nlv = RETRIEVE_FROM_SPEC(spec_found, nonlocal_variable);
WRITE("%s", Data__NonlocalVariables__lvalue_identifier(nlv));
return;
}
#line 399 "inform7/Chapter 16/STORAGE Specifications.w"
;
case PROPERTY_VALUE_SPC:
{
#line 429 "inform7/Chapter 16/STORAGE Specifications.w"
if (Specifications__get_argc(spec_found) != 2) internal_error("malformed PROPERTY_OF SP");
if (Specifications__get_argument(spec_found, 0) == NULL) internal_error("PROPERTY_OF with null arg 0");
if (Specifications__get_argument(spec_found, 1) == NULL) internal_error("PROPERTY_OF with null arg 1");
property *prn = Specifications__Values__get_property_name_if_any(Specifications__get_argument(spec_found, 0));
if (prn == NULL) internal_error("PROPERTY_OF with null property");
specification *prop_spec = Specifications__get_argument(spec_found, 0);
specification *owner = Specifications__get_argument(spec_found, 1);
kind *owner_kind = Specifications__evaluates_to(owner);
{
#line 466 "inform7/Chapter 16/STORAGE Specifications.w"
if (Specifications__Values__is_self_object_constant(owner)) {
inference_subject *infs = Properties__Valued__Conditions__of_what(prn);
instance *I = World__Subjects__as_instance(infs);
if (I) owner = Data__Instances__get_value(I);
}
}
#line 438 "inform7/Chapter 16/STORAGE Specifications.w"
;
WRITE("GProperty(");
Kinds__RuntimeIDs__compile_weak(OUT, owner_kind);
WRITE(", ");
{
#line 483 "inform7/Chapter 16/STORAGE Specifications.w"
if (Specifications__test_flag(spec_found, RECORD_AS_SELF_SPFLAG)) WRITE("self=");
Specifications__compile(OUT, owner);
}
#line 443 "inform7/Chapter 16/STORAGE Specifications.w"
;
WRITE(",");
Specifications__compile(OUT, prop_spec);
WRITE(")");
return;
}
#line 400 "inform7/Chapter 16/STORAGE Specifications.w"
;
case LIST_ENTRY_SPC:
{
#line 489 "inform7/Chapter 16/STORAGE Specifications.w"
if (Specifications__get_argc(spec_found) != 2) internal_error("malformed LIST_OF SP");
if (Specifications__get_argument(spec_found, 0) == NULL) internal_error("LIST_OF with null arg 0");
if (Specifications__get_argument(spec_found, 1) == NULL) internal_error("LIST_OF with null arg 1");
WRITE("LIST_OF_TY_GetItem(");
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__compile(OUT, Specifications__get_argument(spec_found, 0));
END_COMPILATION_MODE;
WRITE(",");
Specifications__compile(OUT, Specifications__get_argument(spec_found, 1));
WRITE(")");
return;
}
#line 401 "inform7/Chapter 16/STORAGE Specifications.w"
;
case TABLE_ENTRY_SPC:
{
#line 505 "inform7/Chapter 16/STORAGE Specifications.w"
switch(Specifications__get_argc(spec_found)) {
case 1:
Code__LocalVariables__used_stack_selection();
Code__LocalVariables__add_table_lookup();
WRITE("TableLookUpEntry(ct_0,");
Specifications__compile(OUT, Specifications__get_argument(spec_found, 0));
WRITE(",ct_1)");
break;
case 2: /* never here except when printing debugging code */
WRITE("(false)");
break;
case 3:
WRITE("TableLookUpEntry(");
Specifications__compile(OUT, Specifications__get_argument(spec_found, 2));
WRITE(",");
Specifications__compile(OUT, Specifications__get_argument(spec_found, 0));
WRITE(",");
Specifications__compile(OUT, Specifications__get_argument(spec_found, 1));
WRITE(")");
break;
case 4:
WRITE("TableLookUpCorr(");
Specifications__compile(OUT, Specifications__get_argument(spec_found, 3));
WRITE(",");
Specifications__compile(OUT, Specifications__get_argument(spec_found, 0));
WRITE(",");
Specifications__compile(OUT, Specifications__get_argument(spec_found, 1));
WRITE(",");
Specifications__compile(OUT, Specifications__get_argument(spec_found, 2));
WRITE(")");
break;
default: internal_error("TABLE REFERENCE with bad number of args");
}
return;
}
#line 402 "inform7/Chapter 16/STORAGE Specifications.w"
;
default: LOG("Offender: $S\n", spec_found);
internal_error("unable to compile this STORAGE species");
}
}
#line 568 "inform7/Chapter 16/STORAGE Specifications.w"
char *Specifications__Storage__storage_class_schema(int 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_SPC: return "*=-*1 = *<2";
case NONLOCAL_VARIABLE_SPC: return "*=-*1 = *<2";
case TABLE_ENTRY_SPC: return "*=-*1*-,1,*<2)";
case PROPERTY_VALUE_SPC: return "*=-Write*+1*-,*<2)";
case LIST_ENTRY_SPC: return "*=-Write*1*-,*<2)";
}
return "";
case STORE_WORD_TO_POINTER:
switch(storage_class) {
case LOCAL_VARIABLE_SPC: return "*=-BlkValueCast(*1, *#2, *!2)";
case NONLOCAL_VARIABLE_SPC: return "*=-BlkValueCast(*1, *#2, *!2)";
case TABLE_ENTRY_SPC: return "*=-BlkValueCast(*1*-,5), *#2, *!2)";
case PROPERTY_VALUE_SPC: return "*=-BlkValueCast(*+1, *#2, *!2)";
case LIST_ENTRY_SPC: return "*=-BlkValueCast(*1, *#2, *!2)";
}
return "";
case STORE_POINTER_TO_POINTER:
switch(storage_class) {
case LOCAL_VARIABLE_SPC: return "*=-BlkValueCopy(*1, *<2)";
case NONLOCAL_VARIABLE_SPC: return "*=-BlkValueCopy(*1, *<2)";
case TABLE_ENTRY_SPC: return "*=-BlkValueCopy(*1*-,5), *<2)";
case PROPERTY_VALUE_SPC: return "*=-BlkValueCopy(*+1, *<2)";
case LIST_ENTRY_SPC: return "*=-BlkValueCopy(*1, *<2)";
}
return "";
case INCREASE_BY_WORD:
if (reducing_modulo_1440) {
switch(storage_class) {
case LOCAL_VARIABLE_SPC: return "*=-*1 = NUMBER_TY_to_TIME_TY(*1 + *<2)";
case NONLOCAL_VARIABLE_SPC: return "*=-*1 = NUMBER_TY_to_TIME_TY(*1 + *<2)";
case TABLE_ENTRY_SPC: return "*=-*1*-,1,NUMBER_TY_to_TIME_TY(*1 + *<2))";
case PROPERTY_VALUE_SPC: return "*=-Write*+1*-,NUMBER_TY_to_TIME_TY(*+1 + *<2))";
case LIST_ENTRY_SPC: return "*=-Write*1*-,NUMBER_TY_to_TIME_TY(*1 + *<2))";
}
} else {
switch(storage_class) {
case LOCAL_VARIABLE_SPC: return "*=-*1 = *1 + *<2";
case NONLOCAL_VARIABLE_SPC: return "*=-*1 = *1 + *<2";
case TABLE_ENTRY_SPC: return "*=-*1*-,1,*1 + *<2)";
case PROPERTY_VALUE_SPC: return "*=-Write*+1*-,*+1 + *<2)";
case LIST_ENTRY_SPC: return "*=-Write*1*-,*1 + *<2)";
}
}
return "";
case INCREASE_BY_REAL:
switch(storage_class) {
case LOCAL_VARIABLE_SPC: return "*=-*1 = REAL_NUMBER_TY_Plus(*1, *<2)";
case NONLOCAL_VARIABLE_SPC: return "*=-*1 = REAL_NUMBER_TY_Plus(*1, *<2)";
case TABLE_ENTRY_SPC: return "*=-*1*-,1,REAL_NUMBER_TY_Plus(*1, *<2))";
case PROPERTY_VALUE_SPC: return "*=-Write*+1*-,REAL_NUMBER_TY_Plus(*+1, *<2))";
case LIST_ENTRY_SPC: 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_SPC: return "*=-*1 = NUMBER_TY_to_TIME_TY(*1 - *<2)";
case NONLOCAL_VARIABLE_SPC: return "*=-*1 = NUMBER_TY_to_TIME_TY(*1 - *<2)";
case TABLE_ENTRY_SPC: return "*=-*1*-,1,NUMBER_TY_to_TIME_TY(*1 - *<2))";
case PROPERTY_VALUE_SPC: return "*=-Write*+1*-,NUMBER_TY_to_TIME_TY(*+1 - *<2))";
case LIST_ENTRY_SPC: return "*=-Write*1*-,NUMBER_TY_to_TIME_TY(*1 - *<2))";
}
} else {
switch(storage_class) {
case LOCAL_VARIABLE_SPC: return "*=-*1 = *1 - *<2";
case NONLOCAL_VARIABLE_SPC: return "*=-*1 = *1 - *<2";
case TABLE_ENTRY_SPC: return "*=-*1*-,1,*1 - *<2)";
case PROPERTY_VALUE_SPC: return "*=-Write*+1*-,*+1 - *<2)";
case LIST_ENTRY_SPC: return "*=-Write*1*-,*1 - *<2)";
}
}
return "";
case DECREASE_BY_REAL:
switch(storage_class) {
case LOCAL_VARIABLE_SPC: return "*=-*1 = REAL_NUMBER_TY_Minus(*1, *<2)";
case NONLOCAL_VARIABLE_SPC: return "*=-*1 = REAL_NUMBER_TY_Minus(*1, *<2)";
case TABLE_ENTRY_SPC: return "*=-*1*-,1,REAL_NUMBER_TY_Minus(*1, *<2))";
case PROPERTY_VALUE_SPC: return "*=-Write*+1*-,REAL_NUMBER_TY_Minus(*+1, *<2))";
case LIST_ENTRY_SPC: return "*=-Write*1*-,REAL_NUMBER_TY_Minus(*1, *<2))";
}
return "";
case DECREASE_BY_POINTER:
internal_error("pointer value decrements not implemented");
return "";
}
return "";
}
#line 158 "inform7/Chapter 16/CONDITION Specifications.w"
int condition_nonkind_types_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 163 "inform7/Chapter 16/CONDITION Specifications.w"
#line 167 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__create_species(void) {
Specifications__Taxa__set_source_name(CONDITION_FMY, "CONDITION_FMY");
Specifications__Taxa__set_parsing_names(CONDITION_FMY,
Text__Languages__word(condition_nonkind_types_NTM, 0),
Text__Languages__word(condition_nonkind_types_NTM, 1));
Specifications__Taxa__permit_pair(CONDITION_FMY, UNKNOWN,
TYPE_PARSED_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT);
Specifications__Taxa__set_flag(CONDITION_FMY, TENSE_SPCFLAG);
Specifications__Taxa__permit_pair(CONDITION_FMY, LOGICAL_AND_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(LOGICAL_AND_SPC, "LOGICAL_AND_SPC");
Specifications__Taxa__set_flag(LOGICAL_AND_SPC, ARGUMENTS_SPCFLAG);
Specifications__Taxa__permit_pair(CONDITION_FMY, LOGICAL_OR_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(LOGICAL_OR_SPC, "LOGICAL_OR_SPC");
Specifications__Taxa__set_flag(LOGICAL_OR_SPC, ARGUMENTS_SPCFLAG);
Specifications__Taxa__permit_pair(CONDITION_FMY, TEST_PROPOSITION_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(TEST_PROPOSITION_SPC, "TEST_PROPOSITION_SPC");
Specifications__Taxa__permit_pair(CONDITION_FMY, NOW_PROPOSITION_SPC,
PARSED_SPCONTEXT + TYPE_PARSED_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT +
TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(NOW_PROPOSITION_SPC, "NOW_PROPOSITION_SPC");
Specifications__Taxa__set_parsing_names(NOW_PROPOSITION_SPC,
Text__Languages__word(condition_nonkind_types_NTM, 2),
Text__Languages__word(condition_nonkind_types_NTM, 3));
Specifications__Taxa__set_flag(CONDITION_FMY, PROPOSITION_SPCFLAG);
Specifications__Taxa__permit_pair(CONDITION_FMY, TEST_PHRASE_OPTION_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(TEST_PHRASE_OPTION_SPC, "TEST_PHRASE_OPTION_SPC");
Specifications__Taxa__permit_pair(CONDITION_FMY, TEST_ACTION_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(TEST_ACTION_SPC, "TEST_ACTION_SPC");
Specifications__Taxa__permit_pair(CONDITION_FMY, TEST_PAST_ACTION_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(TEST_PAST_ACTION_SPC, "TEST_PAST_ACTION_SPC");
Specifications__Taxa__permit_pair(CONDITION_FMY, PHRASE_TO_DECIDE_IF_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(PHRASE_TO_DECIDE_IF_SPC, "PHRASE_TO_DECIDE_IF_SPC");
Specifications__Taxa__set_flag(PHRASE_TO_DECIDE_IF_SPC, PHRASAL_SPCFLAG + INVLIST_SPCFLAG);
Specifications__Taxa__permit_pair(CONDITION_FMY, DESCRIPTION_SPC,
TYPE_PARSED_SPCONTEXT + PARSED_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT +
TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(DESCRIPTION_SPC, "DESCRIPTION_SPC");
Specifications__Taxa__set_flag(CONDITION_FMY, PROPOSITION_SPCFLAG + DOCKET_SPCFLAG);
}
#line 229 "inform7/Chapter 16/CONDITION Specifications.w"
specification *Specifications__Conditions__new(time_period *tp) {
specification *spec = Specifications__new(CONDITION_FMY, UNKNOWN);
Specifications__set_condition_tense(spec, tp);
return spec;
}
#line 238 "inform7/Chapter 16/CONDITION Specifications.w"
specification *Specifications__Conditions__new_generic_CONDITION(void) {
specification *spec = Specifications__Conditions__new(NULL);
Specifications__make_generic(spec);
return spec;
}
#line 247 "inform7/Chapter 16/CONDITION Specifications.w"
specification *Specifications__Conditions__new_LOGICAL_AND(specification *spec1, specification *spec2) {
specification *spec = Specifications__new(CONDITION_FMY, LOGICAL_AND_SPC);
Specifications__set_argument(spec, 0, spec1);
Specifications__set_argument(spec, 1, spec2);
return spec;
}
specification *Specifications__Conditions__new_LOGICAL_OR(specification *spec1, specification *spec2) {
specification *spec = Specifications__new(CONDITION_FMY, LOGICAL_OR_SPC);
Specifications__set_argument(spec, 0, spec1);
Specifications__set_argument(spec, 1, spec2);
return spec;
}
#line 265 "inform7/Chapter 16/CONDITION Specifications.w"
specification *Specifications__Conditions__new_TEST_PROPOSITION(pcalc_prop *prop) {
specification *spec = Specifications__new(CONDITION_FMY, TEST_PROPOSITION_SPC);
Specifications__set_proposition(spec, prop);
return spec;
}
#line 275 "inform7/Chapter 16/CONDITION Specifications.w"
specification *Specifications__Conditions__new_TEST_PHRASE_OPTION(int opt_num) {
specification *spec = Specifications__new(CONDITION_FMY, TEST_PHRASE_OPTION_SPC);
Specifications__set_data(spec, PHRASE_OPTION_SPDATA, opt_num);
return spec;
}
#line 284 "inform7/Chapter 16/CONDITION Specifications.w"
specification *Specifications__Conditions__new_TEST_ACTION(action_pattern *ap) {
specification *spec = Specifications__new(CONDITION_FMY, TEST_ACTION_SPC);
if (ap) ATTACH_TO_SPEC(spec, action_pattern, ap);
return spec;
}
specification *Specifications__Conditions__new_TEST_PAST_ACTION(action_pattern *ap) {
specification *spec = Specifications__new(CONDITION_FMY, TEST_PAST_ACTION_SPC);
if (ap) ATTACH_TO_SPEC(spec, action_pattern, ap);
return spec;
}
#line 300 "inform7/Chapter 16/CONDITION Specifications.w"
specification *Specifications__Conditions__new_PHRASE_TO_DECIDE_IF(void) {
specification *spec = Specifications__new(CONDITION_FMY, PHRASE_TO_DECIDE_IF_SPC);
Specifications__create_invocation_list(spec);
return spec;
}
#line 317 "inform7/Chapter 16/CONDITION Specifications.w"
specification *Specifications__Conditions__new_DESCRIPTION(void) {
specification *spec = Specifications__new(CONDITION_FMY, DESCRIPTION_SPC);
return spec;
}
specification *Specifications__Conditions__new_DESCRIPTION_of(kind *K) {
specification *spec = Specifications__new(CONDITION_FMY, DESCRIPTION_SPC);
Specifications__Conditions__set_described_kind(spec, K);
return spec;
}
#line 333 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__attach_tense(specification *spec, int t) {
if (Specifications__get_condition_tense(spec) == NULL)
Specifications__set_condition_tense(spec,
Code__Chronology__TimePeriods__store(
Code__Chronology__TimePeriods__new_tense_marker(t)));
Code__Chronology__TimePeriods__set_tense(Specifications__get_condition_tense(spec), t);
}
#line 346 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__coerce_TEST_PROPOSITION_to_NOW_PROPOSITION(specification *spec) {
if (spec == NULL) internal_error("can't coerce null type");
if (Specifications__species_is(spec, TEST_PROPOSITION_SPC))
Specifications__coerce_to(spec, CONDITION_FMY, NOW_PROPOSITION_SPC);
else internal_error("tried Specifications__Conditions__coerce_TEST_PROPOSITION_to_NOW_PROPOSITION inapplicably");
}
#line 360 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__coerce_generic_CONSTANT_to_DESCRIPTION(specification *spec) {
if (spec == NULL) internal_error("can't coerce null type");
if (Specifications__Values__is_generic_CONSTANT(spec)) {
kind *K = Specifications__get_kind(spec);
Specifications__coerce_to(spec, CONDITION_FMY, DESCRIPTION_SPC);
Specifications__Conditions__set_described_kind(spec, K);
Specifications__make_actual(spec);
return;
}
internal_error("tried Specifications__Conditions__coerce_generic_CONSTANT_to_DESCRIPTION inapplicably");
}
#line 380 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__is_qualified_DESCRIPTION(specification *spec) {
if ((Specifications__species_is(spec, DESCRIPTION_SPC)) &&
((Specifications__get_proposition(spec)) ||
(Specifications__Conditions__number_of_adjectives_applied_to(spec) > 0)))
return TRUE;
return FALSE;
}
int Specifications__Conditions__is_complex_DESCRIPTION(specification *spec) {
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
if (Specifications__get_proposition(spec)) return TRUE;
}
return FALSE;
}
int Specifications__Conditions__is_adjectives_plus_kind_of_object_DESCRIPTION(specification *spec) {
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
if (Specifications__Conditions__number_of_adjectives_applied_to(spec) == 0)
return FALSE;
kind *K = Specifications__Conditions__get_described_kind(spec);
if ((K) && (Kinds__le(K, K_object))) return TRUE;
}
return FALSE;
}
#line 411 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__restrict_DESCRIPTION_domain(specification *spec, instance *new_instance) {
if (new_instance == NULL) return;
kind *current_kind = Specifications__Conditions__get_described_kind(spec);
instance *current_instance = Specifications__Conditions__get_described_instance(spec);
kind *NK = Data__Instances__kind(new_instance);
if (current_instance == NULL) {
if (current_kind) {
if (Kinds__le(NK, current_kind) == FALSE)
Specifications__Unknown__coerce(spec);
} else Specifications__Conditions__set_described_instance(spec, new_instance);
} else {
kind *CK = Data__Instances__kind(current_instance);
kind *max = Kinds__max(CK, NK);
if (Kinds__lt(max, K_object)) {
Specifications__Conditions__set_described_instance(spec, NULL);
Specifications__Conditions__set_described_kind(spec, max);
} else {
Specifications__Unknown__coerce(spec);
}
}
}
void Specifications__Conditions__restrict_DESCRIPTION_to_kind(specification *spec, kind *NK) {
if (NK == NULL) return;
Specifications__Conditions__set_described_instance(spec, NULL);
Specifications__Conditions__set_described_kind(spec, NK);
}
#line 442 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__write_out_in_English(OUTPUT_STREAM, specification *spec) {
switch (Specifications__get_species(spec)) {
case PHRASE_TO_DECIDE_IF_SPC: WRITE("a yes or no question"); break;
case DESCRIPTION_SPC: {
kind *K = Specifications__get_kind_referred_to(spec);
WRITE("a description");
if (K) {
int w1 = -1, w2 = -1;
Kinds__get_name(K, &w1, &w2, TRUE);
if (w1 >= 0) {
WRITE(" of ");
Text__print_raw_text_to_stream(w1, w2, OUT);
}
}
break;
}
default: WRITE("a condition");
}
}
#line 465 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__log(specification *spec) {
if (Specifications__test_flag(spec, CONDITION_NEGATED_SPFLAG)) LOG("(negated)");
if (Specifications__get_condition_tense(spec)) Code__Chronology__TimePeriods__log(Specifications__get_condition_tense(spec));
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
adjective_list_entry *ale;
int i = 0;
LOOP_THROUGH_ADJECTIVE_LIST(ale, spec) {
if (i == 0) LOG("(adjectives:"); else LOG(",");
LOG("$r", ale);
i++;
}
if (i > 0) LOG(")");
if (Specifications__Conditions__get_described_instance(spec)) LOG("(object $O)", Specifications__Conditions__get_described_instance(spec));
if (Specifications__Conditions__get_described_kind(spec)) LOG("(kind $u)", Specifications__Conditions__get_described_kind(spec));
if (Specifications__get_proposition(spec)) LOG("(such that $D)", Specifications__get_proposition(spec));
}
}
#line 489 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__compare_specificity_of_DESCRIPTIONs(specification *spec1, specification *spec2) {
{
#line 518 "inform7/Chapter 16/CONDITION Specifications.w"
int len1 = Calculus__Propositions__length(Specifications__get_proposition(spec1));
int len2 = Calculus__Propositions__length(Specifications__get_proposition(spec2));
if ((len1 > 0) || (len2 > 0)) {
LOGIF(SPECIFICITIES,
"Test %d: Comparing specificity of props:\n(%d) $D\n(%d) $D\n",
cco, len1, Specifications__get_proposition(spec1), len2, Specifications__get_proposition(spec2));
}
if (len1 > len2) return 1;
if (len1 < len2) return -1;
}
#line 490 "inform7/Chapter 16/CONDITION Specifications.w"
;
{
#line 531 "inform7/Chapter 16/CONDITION Specifications.w"
if (Specifications__Matching__can_we_match_value_descriptions(spec1, spec2) == ALWAYS_MATCH) {
if (Specifications__Matching__can_we_match_value_descriptions(spec2, spec1) != ALWAYS_MATCH) return 1;
} else {
if (Specifications__Matching__can_we_match_value_descriptions(spec2, spec1) == ALWAYS_MATCH) return -1;
}
}
#line 491 "inform7/Chapter 16/CONDITION Specifications.w"
;
{
#line 540 "inform7/Chapter 16/CONDITION Specifications.w"
int count1 = Specifications__Conditions__number_of_adjectives_applied_to(spec1);
int count2 = Specifications__Conditions__number_of_adjectives_applied_to(spec2);
if (count1 > count2) return 1;
if (count1 < count2) return -1;
}
#line 492 "inform7/Chapter 16/CONDITION Specifications.w"
;
{
#line 548 "inform7/Chapter 16/CONDITION Specifications.w"
kind *k1 = Specifications__Conditions__get_described_kind(spec1);
kind *k2 = Specifications__Conditions__get_described_kind(spec2);
if ((k1) && (k2)) {
if (Kinds__lt(k1, k2)) return 1;
if (Kinds__lt(k2, k1)) return -1;
}
}
#line 493 "inform7/Chapter 16/CONDITION Specifications.w"
;
return 0;
}
#line 563 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__compare_specificity_of_CONDITIONs(specification *spec1, specification *spec2) {
if ((spec1 == NULL) && (spec2 == NULL)) return 0;
int count1 = Specifications__Conditions__count(spec1);
int count2 = Specifications__Conditions__count(spec2);
if (count1 > count2) return 1;
if (count1 < count2) return -1;
return 0;
}
#line 578 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__count(specification *spec) {
if (spec == NULL) return 0;
if (Specifications__family_is(spec, CONDITION_FMY) == FALSE) return 1;
switch (Specifications__get_species(spec)) {
case LOGICAL_AND_SPC:
return Specifications__Conditions__count(Specifications__get_argument(spec, 0))
+ Specifications__Conditions__count(Specifications__get_argument(spec, 1));
case LOGICAL_OR_SPC:
return -1;
case TEST_PROPOSITION_SPC:
return Calculus__Propositions__length(Specifications__get_proposition(spec));
case PHRASE_TO_DECIDE_IF_SPC:
case TEST_PHRASE_OPTION_SPC:
case TEST_ACTION_SPC:
case TEST_PAST_ACTION_SPC:
return 1;
}
return 0;
}
#line 602 "inform7/Chapter 16/CONDITION Specifications.w"
kind *Specifications__Conditions__kind_when_CONDITION_is_evaluated(specification *spec) {
return NULL;
}
#line 612 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__compile(OUTPUT_STREAM, specification *spec_found) {
if (Specifications__species_is(spec_found, NOW_PROPOSITION_SPC))
{
#line 651 "inform7/Chapter 16/CONDITION Specifications.w"
if (Specifications__get_proposition(spec_found))
Calculus__Deferrals__compile_now_proposition(OUT,
Specifications__get_proposition(spec_found), TRUE);
return;
}
#line 614 "inform7/Chapter 16/CONDITION Specifications.w"
;
if (Specifications__get_condition_tense(spec_found))
{
#line 663 "inform7/Chapter 16/CONDITION Specifications.w"
Code__Chronology__compile_past_tense_condition(OUT, *(Specifications__get_condition_tense(spec_found)),
Specifications__copy(spec_found));
return;
}
#line 617 "inform7/Chapter 16/CONDITION Specifications.w"
;
WRITE("(");
if (Specifications__test_flag(spec_found, CONDITION_NEGATED_SPFLAG)) WRITE("~~(");
switch (Specifications__get_species(spec_found)) {
case DESCRIPTION_SPC:
WRITE("true"); break; /* purely for problem recovery */
case TEST_PROPOSITION_SPC:
Calculus__Deferrals__compile_test_of_proposition(OUT, NULL, Specifications__get_proposition(spec_found));
break;
case LOGICAL_AND_SPC: case LOGICAL_OR_SPC:
{
#line 670 "inform7/Chapter 16/CONDITION Specifications.w"
if (Specifications__get_argc(spec_found) != 2)
internal_error("Compiled malformed CONDITION/AND SP");
specification *left_operand = Specifications__get_argument(spec_found, 0);
specification *right_operand = Specifications__get_argument(spec_found, 1);
if ((left_operand == NULL) || (right_operand == NULL))
internal_error("Compiled CONDITION/AND with LHS operands");
Specifications__compile(OUT, left_operand);
if (Specifications__species_is(spec_found, LOGICAL_AND_SPC)) WRITE(" && ");
if (Specifications__species_is(spec_found, LOGICAL_OR_SPC)) WRITE(" || ");
Specifications__compile(OUT, right_operand);
}
#line 627 "inform7/Chapter 16/CONDITION Specifications.w"
; break;
case TEST_ACTION_SPC:
Plugins__Actions__Patterns__compile_pattern_match(OUT,
*(RETRIEVE_FROM_SPEC(spec_found, action_pattern)), FALSE);
break;
case TEST_PAST_ACTION_SPC:
Plugins__Actions__Patterns__compile_past_tense(OUT, RETRIEVE_FROM_SPEC(spec_found, action_pattern));
break;
case TEST_PHRASE_OPTION_SPC:
{
#line 689 "inform7/Chapter 16/CONDITION Specifications.w"
WRITE("phrase_options & %d", Specifications__get_data(spec_found, PHRASE_OPTION_SPDATA));
}
#line 635 "inform7/Chapter 16/CONDITION Specifications.w"
; break;
case PHRASE_TO_DECIDE_IF_SPC:
Code__Invocations__Compiler__compile(OUT,
Specifications__invocation_list(spec_found), spec_found->word_ref1);
break;
}
if (Specifications__test_flag(spec_found, CONDITION_NEGATED_SPFLAG)) WRITE(")");
WRITE(")");
}
#line 699 "inform7/Chapter 16/CONDITION Specifications.w"
void spec_clear_docket(specification *spec) {
empty_adjective_list(spec);
Specifications__Conditions__set_described_kind(spec, NULL);
Specifications__Conditions__set_described_instance(spec, NULL);
description_docket *dd = Specifications__get_docket(spec);
dd->calling_w1 = -1;
dd->calling_w2 = -1;
}
description_docket *spec_find_docket(specification *spec, int create_if_necessary) {
if (spec == NULL) {
if (create_if_necessary) internal_error("creating docket for null type");
return NULL;
}
description_docket *dd = Specifications__get_docket(spec);
if (dd == NULL) {
if (create_if_necessary == FALSE) return NULL;
dd = CREATE(description_docket);
Specifications__set_docket(spec, dd);
spec_clear_docket(spec);
dd->quant = NULL;
dd->quant_parameter = 0;
}
return dd;
}
#line 731 "inform7/Chapter 16/CONDITION Specifications.w"
specification *Specifications__Conditions__copy_and_copy_docket(specification *spec) {
if (spec == NULL) return NULL;
specification *nts = Specifications__copy(spec);
if (Specifications__get_docket(spec)) {
description_docket *ndd = CREATE(description_docket);
Specifications__set_docket(nts, ndd);
*ndd = *(Specifications__get_docket(spec));
}
return nts;
}
#line 747 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__convert_docket_to_proposition(specification *spec) {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec, FALSE);
Specifications__set_proposition(spec, prop);
spec_clear_docket(spec);
}
#line 757 "inform7/Chapter 16/CONDITION Specifications.w"
int Specifications__Conditions__number_of_adjectives_applied_to(specification *spec) {
description_docket *dd = spec_find_docket(spec, FALSE);
if (dd == NULL) return 0;
return dd->no_adjectives_applied;
}
int number_of_positive_adjectives_applied_to(specification *spec) {
description_docket *dd = spec_find_docket(spec, FALSE);
if (dd == NULL) return 0;
return dd->no_adjectives_applied;
}
adjective_list_entry *Specifications__Conditions__first_adjective_list_entry(specification *spec) {
description_docket *dd = spec_find_docket(spec, FALSE);
if ((dd == NULL) || (dd->no_adjectives_applied == 0))
internal_error("adjective list has no entries");
return dd->adjectives_applied;
}
void empty_adjective_list(specification *spec) {
description_docket *dd = spec_find_docket(spec, FALSE);
if (dd) {
dd->adjectives_applied = NULL;
dd->no_adjectives_applied = 0;
}
}
void Specifications__Conditions__add_to_adjective_list(adjective_list_entry *ale, specification *spec) {
description_docket *dd = spec_find_docket(spec, TRUE);
dd->no_adjectives_applied++;
ale->next = NULL;
adjective_list_entry *last = dd->adjectives_applied;
if (last == NULL) { dd->adjectives_applied = ale; return; }
while (last->next) last = last->next;
last->next = ale;
}
int types_have_same_adjective_list(specification *spec1, specification *spec2) {
description_docket *dd1 = spec_find_docket(spec1, FALSE);
description_docket *dd2 = spec_find_docket(spec2, FALSE);
if ((dd1 == NULL) && (dd2 == NULL)) return TRUE;
if ((dd1) && (dd2) && (dd1->adjectives_applied == dd2->adjectives_applied)) return TRUE;
return FALSE;
}
#line 805 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__attach_quantifier(specification *spec, quantifier *q, int par) {
description_docket *dd = spec_find_docket(spec, TRUE);
dd->quant = q;
dd->quant_parameter = par;
}
quantifier *Specifications__Conditions__get_quantifier(specification *spec) {
description_docket *dd = spec_find_docket(spec, FALSE);
if (dd == NULL) return NULL;
return dd->quant;
}
int Specifications__Conditions__get_quantification_parameter(specification *spec) {
description_docket *dd = spec_find_docket(spec, FALSE);
if (dd == NULL) return 0;
return dd->quant_parameter;
}
#line 826 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__attach_calling(specification *spec, int c1, int c2) {
description_docket *dd = spec_find_docket(spec, TRUE);
dd->calling_w1 = c1;
dd->calling_w2 = c2;
}
void Specifications__Conditions__get_calling(specification *spec, int *c1, int *c2) {
description_docket *dd = spec_find_docket(spec, FALSE);
if (dd == NULL) { *c1 = -1; *c2 = -1; }
else { *c1 = dd->calling_w1; *c2 = dd->calling_w2; }
}
void Specifications__Conditions__clear_calling(specification *spec) {
description_docket *dd = spec_find_docket(spec, FALSE);
if (dd) { dd->calling_w1 = -1; dd->calling_w2 = -1; }
}
int Specifications__Conditions__makes_callings(specification *spec) {
if (spec == NULL) return FALSE;
int c1, c2;
Specifications__Conditions__get_calling(spec, &c1, &c2);
if (c1 >= 0) return TRUE;
return FALSE;
}
#line 854 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__set_described_kind(specification *spec, kind *K) {
description_docket *dd = spec_find_docket(spec, TRUE);
dd->specific_kind = K;
}
kind *Specifications__Conditions__get_described_kind(specification *spec) {
description_docket *dd = spec_find_docket(spec, FALSE);
if (dd == NULL) return NULL;
return dd->specific_kind;
}
void Specifications__Conditions__set_composite_flag(specification *spec) {
Specifications__set_flag(spec, COMPOSITED_SPFLAG);
}
int Specifications__Conditions__get_composite_flag(specification *spec) {
return Specifications__test_flag(spec, COMPOSITED_SPFLAG);
}
#line 876 "inform7/Chapter 16/CONDITION Specifications.w"
void Specifications__Conditions__set_described_instance(specification *spec, instance *I) {
description_docket *dd = spec_find_docket(spec, TRUE);
dd->specific_object = I;
}
instance *Specifications__Conditions__get_described_instance(specification *spec) {
description_docket *dd = spec_find_docket(spec, FALSE);
if (dd == NULL) return NULL;
return dd->specific_object;
}
#line 896 "inform7/Chapter 16/CONDITION Specifications.w"
adjective_list_entry *Specifications__Conditions__new_adjective_list_entry(adjectival_phrase *aph, int pos) {
adjective_list_entry *ale = CREATE(adjective_list_entry);
ale->ref_to = aph;
ale->ref_positive = pos;
ale->next = NULL;
return ale;
}
void Specifications__Conditions__log_adjective_list_entry(adjective_list_entry *ale) {
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(ale);
if (ale->ref_positive == FALSE) LOG("~");
int w1, w2;
Semantics__Adjectives__Meanings__get_text(aph, &w1, &w2, FALSE);
LOG("<adj:$W>", w1, w2);
}
adjective_list_entry *Specifications__Conditions__copy_adjective_list_entry(adjective_list_entry *ale_from) {
return Specifications__Conditions__new_adjective_list_entry(ale_from->ref_to, ale_from->ref_positive);
}
adjectival_phrase *Specifications__Conditions__get_adjective_from_list_entry(adjective_list_entry *ale) {
if (ale == NULL) return NULL;
return ale->ref_to;
}
int Specifications__Conditions__adjective_used_positively(adjective_list_entry *ale) {
if (ale == NULL) internal_error("null adjective tested for positivity");
return ale->ref_positive;
}
#line 68 "inform7/Chapter 16/COMMAND Specifications.w"
int command_phrase_nonkind_types_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 73 "inform7/Chapter 16/COMMAND Specifications.w"
#line 77 "inform7/Chapter 16/COMMAND Specifications.w"
void Specifications__Commands__create_species(void) {
Specifications__Taxa__set_source_name(COMMAND_FMY, "COMMAND_FMY");
Specifications__Taxa__set_parsing_names(COMMAND_FMY,
Text__Languages__word(command_phrase_nonkind_types_NTM, 0),
Text__Languages__word(command_phrase_nonkind_types_NTM, 1));
Specifications__Taxa__permit_pair(COMMAND_FMY, UNKNOWN,
TYPE_PARSED_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT);
Specifications__Taxa__permit_pair(COMMAND_FMY, TO_PHRASE_SPC,
PARSED_SPCONTEXT + TYPE_PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT +
TYPE_EXPECTED_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(TO_PHRASE_SPC, "TO_PHRASE_SPC");
Specifications__Taxa__set_flag(TO_PHRASE_SPC, PHRASAL_SPCFLAG + INVLIST_SPCFLAG);
Specifications__Taxa__permit_pair(COMMAND_FMY, OTHERWISE_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(OTHERWISE_SPC, "OTHERWISE_SPC");
Specifications__Taxa__set_flag(OTHERWISE_SPC, PHRASAL_SPCFLAG);
Specifications__Taxa__permit_pair(COMMAND_FMY, CASE_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(CASE_SPC, "CASE_SPC");
Specifications__Taxa__set_flag(CASE_SPC, PHRASAL_SPCFLAG + ARGUMENTS_SPCFLAG);
Specifications__Taxa__permit_pair(COMMAND_FMY, END_BLOCK_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(END_BLOCK_SPC, "END_BLOCK_SPC");
Specifications__Taxa__set_flag(END_BLOCK_SPC, PHRASAL_SPCFLAG);
Specifications__Taxa__permit_pair(COMMAND_FMY, RULEBOOK_OUTCOME_PHRASE_SPC,
PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT + TYPE_EXPECTED_SPCONTEXT +
COMPILED_SPCONTEXT);
Specifications__Taxa__set_source_name(RULEBOOK_OUTCOME_PHRASE_SPC,
"RULEBOOK_OUTCOME_PHRASE_SPC");
Specifications__Taxa__set_flag(RULEBOOK_OUTCOME_PHRASE_SPC, PHRASAL_SPCFLAG);
Specifications__Taxa__permit_pair(COMMAND_FMY, TRY_ACTION_SPC,
PARSED_SPCONTEXT + TYPE_PARSED_SPCONTEXT + TYPE_FOUND_SPCONTEXT +
TYPE_EXPECTED_SPCONTEXT + COMPILED_SPCONTEXT);
Specifications__Taxa__set_parsing_names(TRY_ACTION_SPC,
Text__Languages__word(command_phrase_nonkind_types_NTM, 2),
Text__Languages__word(command_phrase_nonkind_types_NTM, 3));
Specifications__Taxa__set_source_name(TRY_ACTION_SPC, "TRY_ACTION_SPC");
Specifications__Taxa__set_flag(TRY_ACTION_SPC, ARGUMENTS_SPCFLAG);
}
#line 128 "inform7/Chapter 16/COMMAND Specifications.w"
specification *Specifications__Commands__new(void) {
specification *spec = Specifications__new(COMMAND_FMY, UNKNOWN);
return spec;
}
specification *Specifications__Commands__new_TO_PHRASE(void) {
specification *spec = Specifications__new(COMMAND_FMY, TO_PHRASE_SPC);
Specifications__create_invocation_list(spec);
return spec;
}
specification *Specifications__Commands__new_OTHERWISE(void) {
specification *spec = Specifications__new(COMMAND_FMY, OTHERWISE_SPC);
return spec;
}
specification *Specifications__Commands__new_CASE(specification *case_val) {
specification *spec = Specifications__new(COMMAND_FMY, CASE_SPC);
Specifications__set_argument(spec, 0, case_val);
return spec;
}
specification *Specifications__Commands__new_default_CASE(void) {
specification *spec = Specifications__new(COMMAND_FMY, CASE_SPC);
return spec;
}
specification *Specifications__Commands__new_RULEBOOK_OUTCOME_COMMAND(named_rulebook_outcome *nro) {
specification *spec = Specifications__new(COMMAND_FMY, RULEBOOK_OUTCOME_PHRASE_SPC);
ATTACH_TO_SPEC(spec, named_rulebook_outcome, nro);
return spec;
}
specification *Specifications__Commands__new_END_BLOCK(phrase *ph) {
specification *spec = Specifications__new(COMMAND_FMY, END_BLOCK_SPC);
ATTACH_TO_SPEC(spec, phrase, ph);
return spec;
}
#line 172 "inform7/Chapter 16/COMMAND Specifications.w"
void Specifications__Commands__coerce_TEST_ACTION_to_TRY_ACTION(specification *spec,
specification *nspec, specification *sspec, specification *aspec,
int other_flag, action_name_list *anl) {
if (spec == NULL) internal_error("Specifications__Commands__coerce_TEST_ACTION_to_TRY_ACTION on NULL");
Specifications__coerce_to(spec, COMMAND_FMY, TRY_ACTION_SPC);
Specifications__set_argument(spec, 0, nspec);
Specifications__set_argument(spec, 1, sspec);
Specifications__set_argument(spec, 2, aspec);
if (other_flag) Specifications__set_flag(spec, ACTION_FOR_OTHER_SPFLAG);
else Specifications__clear_flag(spec, ACTION_FOR_OTHER_SPFLAG);
ATTACH_TO_SPEC(spec, action_name_list, anl);
}
#line 189 "inform7/Chapter 16/COMMAND Specifications.w"
void Specifications__Commands__write_out_in_English(OUTPUT_STREAM, specification *spec) {
WRITE("an instruction to do something");
}
void Specifications__Commands__log(specification *spec) {
}
#line 201 "inform7/Chapter 16/COMMAND Specifications.w"
kind *Specifications__Commands__kind_when_COMMAND_is_evaluated(specification *spec) {
return NULL;
}
#line 208 "inform7/Chapter 16/COMMAND Specifications.w"
int compile_To_phrase_recursion_depth = 0;
void Specifications__Commands__compile(OUTPUT_STREAM, specification *spec_found) {
switch (Specifications__get_species(spec_found)) {
case CASE_SPC:
{
#line 248 "inform7/Chapter 16/COMMAND Specifications.w"
if ((Specifications__get_argc(spec_found) != 0) && (Specifications__get_argc(spec_found) != 1))
internal_error("Compiled malformed CASE SP");
Code__Frames__Blocks__divide_code_block(CASE_DIVISION);
if (Code__Frames__read_division_count(CASE_DIVISION) != 1) WRITE(";\n");
if (Specifications__get_argc(spec_found) == 0) WRITE("default");
else {
specification *case_value = Specifications__get_argument(spec_found, 0);
if (Specifications__Matching__check_without_expectations(
case_value) != NEVER_MATCH)
Specifications__compile(OUT, case_value);
}
WRITE(":\n");
return;
}
#line 212 "inform7/Chapter 16/COMMAND Specifications.w"
;
case END_BLOCK_SPC:
{
#line 240 "inform7/Chapter 16/COMMAND Specifications.w"
Code__Frames__Blocks__close_code_block(OUT);
return;
}
#line 213 "inform7/Chapter 16/COMMAND Specifications.w"
;
case OTHERWISE_SPC:
{
#line 227 "inform7/Chapter 16/COMMAND Specifications.w"
Code__Frames__Blocks__divide_code_block(OTHERWISE_DIVISION);
if (Code__Frames__read_division_count(OTHERWISE_DIVISION) == 2)
Problems__sentence_problem(_P_(C16DoubleOtherwise),
"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.");
WRITE("} else {\n");
return;
}
#line 214 "inform7/Chapter 16/COMMAND Specifications.w"
;
case RULEBOOK_OUTCOME_PHRASE_SPC:
{
#line 310 "inform7/Chapter 16/COMMAND Specifications.w"
Code__Rulebooks__compile_outcome(OUT, RETRIEVE_FROM_SPEC(spec_found, named_rulebook_outcome));
return;
}
#line 215 "inform7/Chapter 16/COMMAND Specifications.w"
;
case TO_PHRASE_SPC:
{
#line 270 "inform7/Chapter 16/COMMAND Specifications.w"
compile_To_phrase_recursion_depth++;
control_structure_phrase *csp =
Parser__Sentences__detect_control_structure(spec_found->word_ref1, spec_found->word_ref2);
if ((compile_To_phrase_recursion_depth > 1) && (csp)) {
Problems__sentence_problem(_P_(C16BlockWithinNonblock),
"structural phrases like 'if', 'repeat', 'while' or 'otherwise' "
"can't be used as part of the abbreviated form of other structural "
"phrases",
"so for instance 'if in darkness, repeat with X running through rooms' "
"is not allowed because the 'repeat' is too important a phrase to be "
"put at the end of a simple 'if' like this. Instead, the 'if' must be "
"written out in full, so for instance 'if in darkness begin; "
"repeat ... begin; ...; end repeat; end if;' would be fine.");
}
if (csp == otherwise_if_CSP) {
if (Code__Frames__Blocks__inside_a_conditional_block() == FALSE) {
Problems__sentence_problem(_P_(C16OtherwiseIfMisplaced),
"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.)");
} if (Code__Frames__read_division_count(OTHERWISE_DIVISION) > 0) {
Problems__sentence_problem(_P_(C16OtherwiseIfAfterOtherwise),
"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'.)");
}
Code__Frames__Blocks__divide_code_block(OTHERWISE_IF_DIVISION);
}
Code__Invocations__Compiler__compile(OUT,
Specifications__invocation_list(spec_found), spec_found->word_ref1);
compile_To_phrase_recursion_depth--;
return;
}
#line 216 "inform7/Chapter 16/COMMAND Specifications.w"
;
case TRY_ACTION_SPC:
{
#line 317 "inform7/Chapter 16/COMMAND Specifications.w"
if (Specifications__get_argc(spec_found) != 3) internal_error("Compiled malformed ACTION SP");
specification *spec0 = Specifications__get_argument(spec_found, 0); /* the noun */
specification *spec1 = Specifications__get_argument(spec_found, 1); /* the second noun */
specification *spec2 = Specifications__get_argument(spec_found, 2); /* the actor */
if ((Specifications__Values__is_CONSTANT_of_kind(spec0, K_understanding)) &&
(parse_nt_against_word_range(nominative_pronoun_NTM, spec0->word_ref1, spec0->word_ref2, NULL, NULL) == FALSE))
Specifications__Values__coerce_UNDERSTANDING_to_TEXT(spec0);
if ((Specifications__Values__is_CONSTANT_of_kind(spec1, K_understanding)) &&
(parse_nt_against_word_range(nominative_pronoun_NTM, spec1->word_ref1, spec1->word_ref2, NULL, NULL) == FALSE))
Specifications__Values__coerce_UNDERSTANDING_to_TEXT(spec1);
action_name_list *anl = RETRIEVE_FROM_SPEC(spec_found, action_name_list);
action_name *an = Plugins__Actions__Lists__get_singleton_action(anl);
LOGIF(EXPRESSIONS, "Compiling from action name list:\n$L\n", anl);
int flag_bits = 0;
if (Kinds__eq(Specifications__evaluates_to(spec0), K_text)) flag_bits += 16;
if (Kinds__eq(Specifications__evaluates_to(spec1), K_text)) flag_bits += 32;
if (flag_bits > 0) Kinds__RunTime__ensure_basic_heap_present();
if (Specifications__test_flag(spec_found, ACTION_FOR_OTHER_SPFLAG)) flag_bits += 1;
WRITE("TryAction(%d, ", flag_bits);
if (spec2) compile_try_action_parameter(OUT, spec2, K_object);
else WRITE("player");
WRITE(", ##%s, ", Plugins__Actions__identifier(an));
if (spec0) compile_try_action_parameter(OUT, spec0, Plugins__Actions__get_data_type_of_noun(an));
else WRITE("0");
WRITE(", ");
if (spec1) compile_try_action_parameter(OUT, spec1, Plugins__Actions__get_data_type_of_second_noun(an));
else WRITE("0");
WRITE(");");
return;
}
#line 217 "inform7/Chapter 16/COMMAND Specifications.w"
;
}
}
#line 357 "inform7/Chapter 16/COMMAND Specifications.w"
void compile_try_action_parameter(OUTPUT_STREAM, specification *spec, kind *required_kind) {
specification *spec_expected = Specifications__kind_as_spec(required_kind);
if (Kinds__eq(required_kind, K_understanding)) {
kind *K = Specifications__evaluates_to(spec);
if ((Kinds__compatible(K, K_understanding)) ||
(Kinds__compatible(K, K_text))) {
spec_expected = spec;
}
}
if (Specifications__Matching__check(spec, spec_expected)) {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__compile(OUT, spec);
END_COMPILATION_MODE;
}
}
#line 42 "inform7/Chapter 16/Type Checking.w"
int Specifications__Matching__can_we_match_value_descriptions(specification *from_spec, specification *to_spec) {
LOGIF(KIND_CHECKING, "[Can we match from: $S to: $S?]\n", from_spec, to_spec);
kind *from = narrowest_kind_of_value_or_description(from_spec);
kind *to = narrowest_kind_of_value_or_description(to_spec);
int result = NEVER_MATCH;
if ((from) && (to)) result = Kinds__compatible(from, to);
else if (to) result = SOMETIMES_MATCH;
if ((Specifications__Conditions__is_qualified_DESCRIPTION(to_spec)) && (result == ALWAYS_MATCH))
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 68 "inform7/Chapter 16/Type Checking.w"
kind *narrowest_kind_of_value_or_description(specification *spec) {
kind *K = NULL;
if ((Specifications__is_evaluating(spec)) || (Specifications__Values__is_actual_CONSTANT(spec)))
K = Specifications__evaluates_to(spec);
else if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
if (Specifications__Conditions__get_described_kind(spec))
K = Specifications__Conditions__get_described_kind(spec);
if (Specifications__get_proposition(spec))
K = Calculus__Propositions__describes_kind(Specifications__get_proposition(spec));
if (spec == NULL) K = K_object;
}
return K;
}
#line 148 "inform7/Chapter 16/Type Checking.w"
int no_gross_problems_thrown = 0;
int problem_count_at_typecheck_start = 0;
#line 160 "inform7/Chapter 16/Type Checking.w"
int problems_issued_during_typechecking(void) {
if (problem_count_at_typecheck_start < problem_count) return TRUE;
return FALSE;
}
#line 169 "inform7/Chapter 16/Type Checking.w"
kind_variable_declaration *most_recent_interpretation = NULL;
#line 185 "inform7/Chapter 16/Type Checking.w"
int Specifications__Matching__check_without_expectations(specification *found) {
return Specifications__Matching__check(found, found);
}
int Specifications__Matching__check(specification *found, specification *expected) {
{
#line 154 "inform7/Chapter 16/Type Checking.w"
no_gross_problems_thrown = 0;
problem_count_at_typecheck_start = problem_count;
}
#line 190 "inform7/Chapter 16/Type Checking.w"
;
int rv = typecheck_recursive(found, expected, 0, 1, NULL);
if (rv == NEVER_MATCH) return FALSE;
return TRUE;
}
#line 213 "inform7/Chapter 16/Type Checking.w"
int unique_TR_call_identifier = 0, TR_call_counter = 0, problem_count_analysed = 0;
int typecheck_recursive(specification *found, specification *expected,
int problem_threshold, int depth, kind **kind_of_var_to_create) {
int outer_id = unique_TR_call_identifier;
int problem_count_before = problem_count;
unique_TR_call_identifier = TR_call_counter++;
LOG_INDENT;
LOG_STAGE_LEFT("try"); LOGIF(MATCHING, " --?--> $S\n", expected);
LOG_INDENT;
int return_value = typecheck_recursive_inner(found, expected, problem_threshold,
depth, kind_of_var_to_create);
LOG_OUTDENT;
switch(return_value) {
case ALWAYS_MATCH: LOG_STAGE("always match"); break;
case SOMETIMES_MATCH: LOG_STAGE("sometimes match"); break;
case NEVER_MATCH: LOG_STAGE("never match"); break;
default: internal_error("impossible verdict from recursive typechecker");
}
LOG_OUTDENT;
{
#line 253 "inform7/Chapter 16/Type Checking.w"
if ((problem_count > problem_count_analysed) &&
(problem_count > problem_count_before) &&
(Specifications__is_phrasal(found))) {
invocation_list *invl = Specifications__invocation_list(found);
if (invl) {
it_is_not_worth_adding = TRUE;
{
#line 272 "inform7/Chapter 16/Type Checking.w"
int c = 0;
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_INVOCATION_LIST(inv, invl) c++;
Problems__issue_problem_begin("*");
Problems__quote_number(1, &c);
if (c > 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();
int i = 0, last_interesting_group = -1, current_group = -1,
group_interesting = TRUE, all_untested = TRUE;
LOOP_THROUGH_INVOCATION_LIST(inv, invl) {
int g = Code__Invocations__get_group(inv);
if (g != current_group) {
if ((group_interesting) && (current_group >= 0) && (all_untested == FALSE))
last_interesting_group = current_group;
group_interesting = TRUE; all_untested = TRUE;
current_group = g;
}
LOG("%d. $e\n", g, inv);
if ((Code__Invocations__test_flag(inv, PASSED_INVFLAG))
|| (Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG)))
group_interesting = FALSE;
if ((Code__Invocations__test_flag(inv, TESTED_INVFLAG))
|| (Code__Invocations__test_flag(inv, PASSED_INVFLAG))
|| (Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG))
|| (Code__Invocations__test_flag(inv, GROSSLY_FAILED_INVFLAG)))
all_untested = FALSE;
}
if ((group_interesting) && (current_group >= 0) && (all_untested == FALSE))
last_interesting_group = current_group;
LOOP_THROUGH_INVOCATION_LIST(inv, invl) {
int g = Code__Invocations__get_group(inv);
if ((c > 1) && (last_interesting_group >= 0) &&
(g != last_interesting_group)) continue;
i++;
Problems__quote_number(1, &i);
Problems__quote_invocation(2, inv);
Problems__issue_problem_begin("***");
if (c > 1) Problems__issue_problem_segment("%1. %2");
else Problems__issue_problem_segment("%2");
Problems__issue_problem_end();
}
}
#line 259 "inform7/Chapter 16/Type Checking.w"
;
{
#line 319 "inform7/Chapter 16/Type Checking.w"
inv_token_problem_token *itpt;
int any = FALSE;
LOOP_OVER(itpt, inv_token_problem_token)
if (itpt->already_described == FALSE) {
itpt->already_described = TRUE;
if (any == FALSE) {
any = TRUE;
Problems__issue_problem_begin("*");
Problems__issue_problem_segment(
"This was what I found out:");
Problems__issue_problem_end();
}
Problems__quote_words(1, itpt->word_ref1, itpt->word_ref2);
Problems__quote_spec(2, itpt->as_parsed);
Problems__issue_problem_begin("***");
if (Specifications__is_evaluating(itpt->as_parsed)) {
kind *K = Specifications__evaluates_to(itpt->as_parsed);
Problems__quote_kind(3, K);
if (Specifications__family_is(itpt->as_parsed, STORAGE_FMY))
Problems__issue_problem_segment("%1 = <i>%2</i>, holding <i>%3</i>");
else if (Specifications__species_is(itpt->as_parsed, PHRASE_TO_DECIDE_VALUE_SPC)) {
char *seg = "%1 = <i>%2</i>, which results in <i>%3</i>";
invocation_list *found_invl = Specifications__invocation_list(itpt->as_parsed);
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_INVOCATION_LIST(inv, found_invl) {
LOG("$e\n", inv);
if ((Code__Invocations__test_flag(inv, TESTED_INVFLAG)) ||
(Code__Invocations__test_flag(inv, GROSSLY_FAILED_INVFLAG))) {
seg = "%1 = <i>%2</i>, which looks as if it should be <i>%3</i>, "
"but which I can't make sense of";
int i;
for (i=0; i<Code__Invocations__get_number_tokens(inv); i++) {
specification *tok = Code__Invocations__get_token_as_parsed(inv, i);
if (Specifications__is_UNKNOWN(tok)) {
Problems__quote_words(4, tok->word_ref1, tok->word_ref2);
seg = "%1 = <i>%2</i>, which ought to be <i>%3</i>, "
"but which I can't perform because '%4' doesn't make sense here";
break;
}
}
}
}
Problems__issue_problem_segment(seg);
} else {
char *seg = "%1 = <i>%3</i>";
if (Specifications__Values__is_actual_CONSTANT_construction(itpt->as_parsed, CON_property)) {
property *prn = RETRIEVE_POINTER_property(Specifications__get_structure_field(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);
LOG("So $2\n", bp);
}
}
}
Problems__issue_problem_segment(seg);
}
} else {
Problems__issue_problem_segment("%1 = <i>%2</i>");
}
Problems__issue_problem_end();
}
}
#line 260 "inform7/Chapter 16/Type Checking.w"
;
it_is_not_worth_adding = FALSE;
}
problem_count_analysed = problem_count;
}
}
#line 237 "inform7/Chapter 16/Type Checking.w"
;
unique_TR_call_identifier = outer_id;
return return_value;
}
#line 387 "inform7/Chapter 16/Type Checking.w"
int typecheck_recursive_inner(specification *found, specification *expected,
int problem_threshold, int depth, kind **kind_of_var_to_create) {
if ((expected) && (!(Specifications__is_UNKNOWN(expected))))
Specifications__Taxa__observe(expected, TYPE_EXPECTED_SPCONTEXT);
if ((found) && (!(Specifications__is_UNKNOWN(found))))
Specifications__Taxa__observe(found, TYPE_FOUND_SPCONTEXT);
if (Specifications__Values__is_generic_CONSTANT(found))
{
#line 427 "inform7/Chapter 16/Type Checking.w"
int x = NEVER_MATCH;
if (Specifications__Values__is_generic_CONSTANT(expected))
x = Kinds__compatible(Specifications__get_kind(found),
Specifications__get_kind(expected));
Specifications__Conditions__coerce_generic_CONSTANT_to_DESCRIPTION(found);
if (x != NEVER_MATCH) return x;
}
#line 395 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__is_generic(found)) internal_error("type-check on a generic found specification");
{
#line 477 "inform7/Chapter 16/Type Checking.w"
int best_result = ALWAYS_MATCH; /* drops to |SOMETIMES_MATCH| if a need for run-time checking is realised */
{
#line 507 "inform7/Chapter 16/Type Checking.w"
{
#line 516 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(a.1)");
if (Specifications__species_is(expected, NEW_LOCAL_VARIABLE_NAME_SPC)) {
if (Code__LocalVariables__permit_as_new_local(found, FALSE)) {
kind *K = K_value;
if (Specifications__get_kind(expected))
K = Specifications__get_kind(expected);
if (kind_of_var_to_create) *kind_of_var_to_create = K;
return ALWAYS_MATCH;
}
{
#line 535 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
if (Specifications__Conditions__get_described_kind(found))
Problems__quote_text(3, "a kind of value");
else
Problems__quote_kind_of(3, found);
Problems__quote_kind_of(4, expected);
Problems__handmade_problem(_P_(C16KindOfVariable));
Problems__issue_problem_segment(
"In the sentence %1, I was expecting that '%2' would be a variable "
"name (specifically %4), but it turned out to be %3.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 525 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 507 "inform7/Chapter 16/Type Checking.w"
;
{
#line 559 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(a.2)");
if (Specifications__is_UNKNOWN(found)) {
THIS_IS_A_GROSS_PROBLEM;
LOG("(a.2) problem message:\nfound: $Xexpected: $X", found, expected);
if ((Specifications__species_is(expected, TRY_ACTION_SPC)) ||
(Specifications__Values__is_CONSTANT_of_kind(expected, K_stored_action)))
{
#line 600 "inform7/Chapter 16/Type Checking.w"
specification *spec = NULL;
kind *K = NULL, *K2 = NULL;
Plugins__Actions__Patterns__clear_validation_case();
parse_nt_against_word_range(action_pattern_NTM, found->word_ref1, found->word_ref2, NULL, NULL);
if (Plugins__Actions__Patterns__get_validation_case(&spec, &K, &K2)) {
Problems__handmade_problem(_P_(C16UnknownTryAction1));
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_words(3, spec->word_ref1, spec->word_ref2);
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__sentence_problem(_P_(C16UnknownTryAction2),
"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 566 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__family_is(expected, COMMAND_FMY))
{
#line 717 "inform7/Chapter 16/Type Checking.w"
if (parse_nt_against_word_range(structural_phrase_problem_diagnosis_NTM, found->word_ref1, found->word_ref2, NULL, NULL) == FALSE) {
if (Text__mismatched_brackets(found->word_ref1, found->word_ref2)) {
Problems__sentence_problem(_P_(C16UnpairedBrackets),
"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__sentence_problem(_P_(C16UnknownPhrase),
"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 568 "inform7/Chapter 16/Type Checking.w"
;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_spec(3, expected);
int shape = NO_UTSHAPE;
if (current_sentence) {
parse_nt_against_word_range(unknown_text_shape_NTM, current_sentence->word_ref1, current_sentence->word_ref2, NULL, NULL);
shape = most_recent_result;
}
if (shape == NO_UTSHAPE) {
parse_nt_against_word_range(unknown_text_shape_NTM, found->word_ref1, found->word_ref2, NULL, NULL);
shape = most_recent_result;
}
int preceding = found->word_ref1 - 1;
if ((preceding >= 0) && (current_sentence) &&
(((compiling_text_routines_mode) || (shape == SAY_UTSHAPE))) &&
((preceding == current_sentence->word_ref1) || (Text__word(preceding) == COMMA_V)))
{
#line 823 "inform7/Chapter 16/Type Checking.w"
parse_nt_against_word_range(unknown_text_substitution_problem_diagnosis_NTM, found->word_ref1, found->word_ref2, NULL, NULL);
}
#line 587 "inform7/Chapter 16/Type Checking.w"
else if ((Specifications__family_is(expected, CONDITION_FMY)) &&
(shape == LIST_UTSHAPE))
{
#line 834 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16CompoundConditionFailed));
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. ");
parse_nt_against_word_range(condition_problem_diagnosis_NTM, found->word_ref1, found->word_ref2, 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 590 "inform7/Chapter 16/Type Checking.w"
else
{
#line 980 "inform7/Chapter 16/Type Checking.w"
kind *problem_context_kind = Specifications__get_kind(expected);
if (Kinds__eq(problem_context_kind, K_use_option)) {
parse_nt_against_word_range(unknown_use_option_diagnosis_NTM, found->word_ref1, found->word_ref2, NULL, NULL);
} else if (Kinds__get_construct(problem_context_kind) == CON_activity) {
parse_nt_against_word_range(unknown_activity_diagnosis_NTM, found->word_ref1, found->word_ref2, NULL, NULL);
} else {
parse_nt_against_word_range(unknown_value_problem_diagnosis_NTM, found->word_ref1, found->word_ref2, NULL, NULL);
}
}
#line 592 "inform7/Chapter 16/Type Checking.w"
;
return NEVER_MATCH;
}
}
#line 508 "inform7/Chapter 16/Type Checking.w"
;
}
#line 478 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1001 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(b)");
if ((Specifications__is_evaluating(found)) && (Specifications__Values__is_actual_CONSTANT(expected)) &&
(found != expected)) {
kind *kind_found = Specifications__evaluates_to(found);
kind *kind_expected = Specifications__get_kind(expected);
int failed = FALSE;
if (Kinds__uses_pointer_values(kind_found)) {
best_result = SOMETIMES_MATCH;
LOGIF(MATCHING, "dropping to sometimes level for block value comparison\n"); /* see below */
} else if (Specifications__Values__is_actual_CONSTANT(found)) {
if (!(Specifications__Values__compare_CONSTANT(found, expected))) failed = TRUE;
} else if (Kinds__eq(kind_found, K_value)) {
best_result = SOMETIMES_MATCH;
LOGIF(MATCHING, "dropping to sometimes level for polymorphism\n"); /* see below */
} else if (Kinds__compatible(kind_found, kind_expected) != NEVER_MATCH) {
best_result = SOMETIMES_MATCH;
LOGIF(MATCHING, "dropping to sometimes level for value matching\n");
} else failed = TRUE;
if (failed)
{
#line 1044 "inform7/Chapter 16/Type Checking.w"
LOGIF(MATCHING, "(b) on $S rejected: found $u, expected $u\n",
found, kind_found, kind_expected);
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_spec(3, found);
Problems__quote_spec(4, expected);
Problems__handmade_problem(_P_(C16NotExactValueWanted));
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 1020 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 479 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1064 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(c)");
if (Specifications__Values__is_CONSTANT_construction(found, CON_property)) {
property *prn = Properties__from_specification(found);
if (Specifications__Values__is_generic_CONSTANT_construction(expected, CON_property) == FALSE) {
{
#line 1077 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(c.1)");
if (Specifications__Values__is_generic_CONSTANT_construction(expected, CON_property))
return ALWAYS_MATCH;
}
#line 1068 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1085 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(c.2)");
if ((Specifications__Storage__get_storage_form(expected) == PROPERTY_VALUE_SPC) ||
(Specifications__Storage__is_generic(expected))) {
if (Properties__is_value_property(prn)) {
{
#line 1139 "inform7/Chapter 16/Type Checking.w"
specification *become = Specifications__Storage__new_PROPERTY_VALUE(Specifications__copy(found), Specifications__Values__new_self_object_constant());
*found = *become;
Specifications__set_flag(found, COERCED_SPFLAG);
LOGIF(MATCHING, "(c) coercing PROPERTY to PROPERTY VALUE: $S\n", found);
}
#line 1089 "inform7/Chapter 16/Type Checking.w"
;
return ALWAYS_MATCH;
}
}
}
#line 1069 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1105 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(c.3)");
if (Specifications__Values__is_generic_CONSTANT(expected)) {
if (Properties__is_value_property(prn)) {
kind *kind_if_coerced = Properties__Valued__kind(prn);
kind *kind_expected = Specifications__get_kind(expected);
int verdict = Kinds__compatible(kind_if_coerced, kind_expected);
if (verdict != NEVER_MATCH) {
{
#line 1139 "inform7/Chapter 16/Type Checking.w"
specification *become = Specifications__Storage__new_PROPERTY_VALUE(Specifications__copy(found), Specifications__Values__new_self_object_constant());
*found = *become;
Specifications__set_flag(found, COERCED_SPFLAG);
LOGIF(MATCHING, "(c) coercing PROPERTY to PROPERTY VALUE: $S\n", found);
}
#line 1112 "inform7/Chapter 16/Type Checking.w"
;
return verdict;
}
if ((Kinds__get_construct(kind_expected) == CON_description) &&
(Kinds__get_construct(kind_if_coerced) != CON_relation)) {
LOGIF(MATCHING, "(c.3) coercing to description\n");
specification *become = Specifications__Conditions__new_DESCRIPTION();
Specifications__Conditions__set_described_kind(become, kind_if_coerced);
become->word_ref1 = found->word_ref1; become->word_ref2 = found->word_ref2;
Specifications__Values__coerce_DESCRIPTION_to_VALUE(become, kind_if_coerced);
*found = *become;
Specifications__set_flag(found, COERCED_SPFLAG);
} else {
LOGIF(MATCHING, "(c.3) declining to cast into property value form\n");
return verdict;
}
}
}
}
#line 1070 "inform7/Chapter 16/Type Checking.w"
;
}
}
}
#line 480 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1147 "inform7/Chapter 16/Type Checking.w"
{
#line 1158 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(d.1)");
char *desired_to = NULL;
if (Specifications__species_is(found, TEST_PROPOSITION_SPC)) desired_to = "be a condition";
if (Specifications__species_is(found, DESCRIPTION_SPC)) desired_to = "be a description";
if (desired_to) {
if (Calculus__Propositions__type_check(Specifications__get_proposition(found), Calculus__Propositions__tc_no_problem_reporting())
== NEVER_MATCH) {
LOGIF(MATCHING, "(d.1) on $S failed proposition type-checking\n", found);
THIS_IS_A_GROSS_PROBLEM;
Calculus__Propositions__type_check(Specifications__get_proposition(found),
Calculus__Propositions__tc_problem_reporting(found->word_ref1, found->word_ref2, desired_to));
return NEVER_MATCH;
}
}
}
#line 1147 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1185 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(d.2)");
if (Specifications__species_is(expected, NOW_PROPOSITION_SPC)) {
if (Specifications__species_is(found, TEST_PROPOSITION_SPC))
Specifications__Conditions__coerce_TEST_PROPOSITION_to_NOW_PROPOSITION(found);
else if (Specifications__family_is(found, CONDITION_FMY))
{
#line 1196 "inform7/Chapter 16/Type Checking.w"
THIS_IS_A_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
if (Specifications__species_is(found, PHRASE_TO_DECIDE_IF_SPC)) {
Problems__handmade_problem(_P_(C16BadNow1));
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 (Specifications__species_is(found, LOGICAL_AND_SPC)) {
Problems__handmade_problem(_P_(C16BadNow2));
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__handmade_problem(_P_(C16BadNow3));
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();
}
return NEVER_MATCH;
}
#line 1190 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 1148 "inform7/Chapter 16/Type Checking.w"
;
}
#line 481 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1230 "inform7/Chapter 16/Type Checking.w"
{
#line 1243 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(e.1)");
if ((Specifications__species_is(found, TEST_ACTION_SPC)) && (Specifications__species_is(expected, TRY_ACTION_SPC))) {
action_pattern *ap = RETRIEVE_FROM_SPEC(found, action_pattern);
if (Plugins__Actions__Patterns__is_unspecific(ap)) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__handmade_problem(_P_(C16ActionNotSpecific));
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 (Plugins__Actions__Patterns__is_overspecific(ap)) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__handmade_problem(_P_(C16ActionTooSpecific));
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;
}
Plugins__Actions__Patterns__coerce_TEST_ACTION_to_TRY_ACTION(found, ap);
return ALWAYS_MATCH;
}
}
#line 1230 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1288 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(e.2)");
if ((Specifications__Values__is_CONSTANT_of_kind(found, K_text)) &&
(Specifications__Values__is_CONSTANT_of_kind(expected, K_understanding))) {
Specifications__set_flag(found, COERCED_SPFLAG);
Specifications__set_kind_of_value(found, K_understanding);
}
}
#line 1231 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1305 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(e.3)");
kind *domain = NULL;
if (Specifications__Values__is_CONSTANT_construction(expected, CON_description)) {
kind *desc = Specifications__get_kind(expected);
domain = Kinds__unary_construction_material(desc);
}
if ((domain) && (Specifications__species_is(found, DESCRIPTION_SPC))) {
LOGIF(MATCHING, "(e.3) requiring description of $u\n", domain);
kind *K = Specifications__get_kind_referred_to(found);
if (K == NULL) K = K_object;
LOGIF(MATCHING, "(e.3) finding description of $u\n", K);
int made_match = TRUE;
if (Kinds__compatible(K, domain) == NEVER_MATCH) made_match = FALSE;
{
#line 1330 "inform7/Chapter 16/Type Checking.w"
if (made_match == FALSE) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_kind(3, K);
Problems__quote_kind(4, domain);
Problems__handmade_problem(_P_(C16WrongDescriptionAsNoun));
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 1318 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__Values__coerce_DESCRIPTION_to_VALUE(found, K) == FALSE)
{
#line 1350 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__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 1320 "inform7/Chapter 16/Type Checking.w"
;
return ALWAYS_MATCH;
}
}
#line 1232 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1369 "inform7/Chapter 16/Type Checking.w"
if (Specifications__family_is(found, STORAGE_FMY)) {
kind *K = Specifications__evaluates_to(found);
if (K == NULL) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__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 1233 "inform7/Chapter 16/Type Checking.w"
;
}
#line 482 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1399 "inform7/Chapter 16/Type Checking.w"
int exceptional_case = FALSE;
{
#line 1417 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(f.1)");
if ((Specifications__species_is(expected, DESCRIPTION_SPC)) &&
(Specifications__is_actual(expected)) &&
(found != expected)) {
kind *K = Specifications__Conditions__get_described_kind(expected);
if ((Specifications__Values__is_nothing_object_constant(found)) &&
(K) && (Kinds__lt(K, K_object)))
{
#line 1446 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_kind(3, K);
Problems__handmade_problem(_P_(C16NothingForSomething));
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 1424 "inform7/Chapter 16/Type Checking.w"
;
int rv = NEVER_MATCH;
if (!(Specifications__species_is(found, DESCRIPTION_SPC))) {
if (Specifications__species_is(found, PHRASE_TO_DECIDE_VALUE_SPC))
typecheck_recursive(found, found, 2, depth+1, NULL);
rv = Specifications__Matching__can_we_match_value_descriptions(found, expected);
}
if (rv == NEVER_MATCH)
{
#line 1460 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
if (Specifications__Conditions__get_described_kind(expected))
Problems__quote_kind(3, Specifications__Conditions__get_described_kind(expected));
else Problems__quote_words(3, expected->word_ref1, expected->word_ref2);
if (Specifications__species_is(found, DESCRIPTION_SPC)) {
LOG("Description found: $S\nDescription expected: $S\n", found, expected);
if (Specifications__get_proposition(found)) {
Problems__handmade_problem(_P_(C16GenericDescription));
Problems__issue_problem_segment(
"In the line %1, I read '%2' where I was expecting to find 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 {
Problems__handmade_problem(_P_(C16NotSpecificDescription2));
Problems__issue_problem_segment(
"In the line %1, I read '%2' where I was expecting to find a "
"(single) specific example of '%3'.");
Problems__issue_problem_end();
}
} else {
LOG("Found: $u; Expected: $u\n", Specifications__evaluates_to(found),
Specifications__evaluates_to(expected));
if (Specifications__Values__is_actual_CONSTANT_object(found))
Problems__quote_kind(4, Data__Instances__kind(instance_spec_to_instance(found)));
else
Problems__quote_spec(4, found);
Problems__handmade_problem(_P_(C16WrongKind));
Problems__issue_problem_segment(
"You wrote %1, but '%2' has the wrong kind of value to go there: %4 "
"instead of %3.");
Problems__issue_problem_end();
}
return NEVER_MATCH;
}
#line 1433 "inform7/Chapter 16/Type Checking.w"
;
best_result = rv;
if (rv == SOMETIMES_MATCH)
LOGIF(MATCHING, "dropping to sometimes level for description\n");
exceptional_case = TRUE;
}
}
#line 1400 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1512 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(f.2)");
if ((Specifications__species_is(expected, CONSTANT_SPC)) &&
(Specifications__is_evaluating(found)) &&
(found != expected)) {
if (Specifications__species_is(found, PHRASE_TO_DECIDE_VALUE_SPC)) {
LOGIF(MATCHING, "(f.2) exempting phrase from return value checking for now\n");
} else {
switch (Specifications__Matching__can_we_match_value_descriptions(found, expected)) {
case NEVER_MATCH:
{
#line 1536 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_kind_of(3, expected);
if (Specifications__species_is(found, LOCAL_VARIABLE_SPC)) {
local_variable *lvar = RETRIEVE_FROM_SPEC(found, local_variable);
Problems__quote_kind(4, Code__LocalVariables__kind(lvar));
Problems__handmade_problem(_P_(C16LocalMismatch));
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 {
LOG("Found: $u; Expected: $u\n", Specifications__evaluates_to(found),
Specifications__evaluates_to(expected));
Problems__quote_kind(4, Specifications__evaluates_to(found));
Problems__handmade_problem(_P_(C16TypeMismatch));
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 1521 "inform7/Chapter 16/Type Checking.w"
;
case SOMETIMES_MATCH:
best_result = SOMETIMES_MATCH;
LOGIF(MATCHING, "dropping to sometimes level\n");
break;
case ALWAYS_MATCH: break;
}
}
exceptional_case = TRUE;
}
}
#line 1401 "inform7/Chapter 16/Type Checking.w"
;
if (exceptional_case == FALSE)
{
#line 1566 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(f.3)");
int mtf = Specifications__get_family(found), stf = Specifications__get_species(found);
int mte = Specifications__get_family(expected), ste = Specifications__get_species(expected);
if ((mtf != mte) || ((ste != UNKNOWN) && (stf != ste))) {
if ((Specifications__species_is(found, DESCRIPTION_SPC)) &&
(Specifications__Values__is_generic_CONSTANT(expected)))
{
#line 1583 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_kind_of(3, expected);
Problems__quote_kind_of(4, found);
Problems__handmade_problem(_P_(C16LiteralDescriptionAsValue));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is used in a context where I'd expect to see "
"a value, not a description.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 1573 "inform7/Chapter 16/Type Checking.w"
else if (Specifications__Storage__is_generic(expected))
{
#line 1599 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_kind_of(3, expected);
Problems__quote_kind_of(4, found);
Problems__handmade_problem(_P_(C16ValueAsStorageItem));
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 1575 "inform7/Chapter 16/Type Checking.w"
else
{
#line 1621 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_kind_of(3, expected);
Problems__quote_kind_of(4, found);
Problems__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 1577 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 1402 "inform7/Chapter 16/Type Checking.w"
;
}
#line 483 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__get_argc(found) > 0)
{
#line 1640 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(g)");
if ((Specifications__species_is(found, LOGICAL_AND_SPC)) ||
(Specifications__species_is(found, LOGICAL_OR_SPC)))
{
#line 1670 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(g.1)");
specification *cond_spec = Specifications__Conditions__new_generic_CONDITION();
if (typecheck_recursive(Specifications__get_argument(found, 0),
cond_spec, problem_threshold, depth+1, NULL) != ALWAYS_MATCH)
return NEVER_MATCH;
if (typecheck_recursive(Specifications__get_argument(found, 1),
cond_spec, problem_threshold, depth+1, NULL) != ALWAYS_MATCH)
return NEVER_MATCH;
}
#line 1643 "inform7/Chapter 16/Type Checking.w"
else {
int i, an_arg_failed = FALSE;
for (i=0; i<Specifications__get_argc(found); i++) {
specification *ith_argument = Specifications__get_argument(found, i);
if (ith_argument) {
int rv = NEVER_MATCH;
if (!(Specifications__is_UNKNOWN(ith_argument)))
rv = typecheck_recursive(ith_argument, ith_argument,
2, depth+1, NULL);
if (rv != ALWAYS_MATCH) an_arg_failed = TRUE;
}
}
if (Specifications__species_is(found, LIST_ENTRY_SPC))
{
#line 1682 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(g.2)");
kind *K1 = Specifications__evaluates_to(Specifications__get_argument(found, 0));
kind *K2 = Specifications__evaluates_to(Specifications__get_argument(found, 1));
if (Kinds__unary_construction_material(K1) == NULL) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__sentence_problem(_P_(C16EntryOfNonList),
"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__eq(K2, K_number) == FALSE) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__sentence_problem(_P_(C16NonNumericListEntry),
"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 1657 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__species_is(found, PROPERTY_VALUE_SPC))
{
#line 1708 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(g.3)");
specification *the_property = Specifications__get_argument(found, 0);
kind *K1 = Specifications__evaluates_to(the_property);
if (Kinds__get_construct(K1) != CON_property)
{
#line 1734 "inform7/Chapter 16/Type Checking.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_words(3, the_property->word_ref1, the_property->word_ref2);
Problems__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 1711 "inform7/Chapter 16/Type Checking.w"
;
property *prn = Properties__from_specification(the_property);
if (prn == NULL)
internal_error("null property name in type checking");
if (Properties__is_either_or(prn))
{
#line 1748 "inform7/Chapter 16/Type Checking.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__handmade_problem(_P_(C16EitherOrAsValue));
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 1715 "inform7/Chapter 16/Type Checking.w"
;
specification *the_owner = Specifications__get_argument(found, 1);
kind *K2 = Specifications__evaluates_to(the_owner);
if (K2 == NULL)
{
#line 1762 "inform7/Chapter 16/Type Checking.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
if ((Specifications__Conditions__get_described_kind(the_owner)) &&
(Specifications__Conditions__get_quantifier(the_owner) == NULL))
Problems__quote_kind(3, Specifications__Conditions__get_described_kind(the_owner));
else
Problems__quote_words(3, the_owner->word_ref1, the_owner->word_ref2);
Problems__handmade_problem(_P_(C16PropertyOfKind));
if (found->word_ref1 >= 0)
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. ");
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 1720 "inform7/Chapter 16/Type Checking.w"
;
if (Kinds__le(K2, K_object) == FALSE) {
inference_subject *owning_subject = World__Subjects__from_specification(the_owner);
if (owning_subject == NULL) owning_subject = Kinds__as_subject(K2);
if (World__Permissions__find(owning_subject, prn, TRUE) == NULL)
{
#line 1792 "inform7/Chapter 16/Type Checking.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, prn->word_ref1, prn->word_ref2);
Problems__quote_subject(3, owning_subject);
Problems__handmade_problem(_P_(C16LookedUpForbiddenProperty));
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 1726 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 1659 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__species_is(found, TABLE_ENTRY_SPC))
{
#line 1806 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(g.4)");
if ((Specifications__get_argc(found) == 2) &&
(Specifications__species_is(expected, TABLE_ENTRY_SPC) == FALSE)) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__sentence_problem(_P_(C16InexplicitTableEntryAsValue),
"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;
}
if (Specifications__get_argc(found) == 4) {
kind *col_kind = Specifications__evaluates_to(Specifications__get_argument(found, 1));
kind *col_contents_kind = Kinds__unary_construction_material(col_kind);
kind *key_kind = Specifications__evaluates_to(Specifications__get_argument(found, 2));
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__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__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__handmade_problem(_P_(C16TableCorrFruitless));
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 1661 "inform7/Chapter 16/Type Checking.w"
;
if (an_arg_failed) return NEVER_MATCH;
}
}
#line 484 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__family_is(found, COMMAND_FMY))
{
#line 1852 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE_LEFT("(h)");
char *block_name = Code__Frames__Blocks__name_of_current_block();
LOGIF(MATCHING, "Current block: <%s>\n", (block_name)?(block_name):"none");
{
#line 1864 "inform7/Chapter 16/Type Checking.w"
if (Specifications__species_is(found, RULEBOOK_OUTCOME_PHRASE_SPC)) {
if (phrase_being_compiled) {
int ram = Code__Phrases__Usage__get_effect(&(phrase_being_compiled->usage_data));
if ((ram != RULE_IN_RULEBOOK_EFF) &&
(ram != RULE_NOT_IN_RULEBOOK_EFF)) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__handmade_problem(_P_(C16MisplacedRulebookOutcome2));
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();
return NEVER_MATCH;
}
}
named_rulebook_outcome *nrbo = RETRIEVE_FROM_SPEC(found, named_rulebook_outcome);
rulebook *rb = Code__Rulebooks__allow_outcome(nrbo);
if (rb == NULL) return ALWAYS_MATCH;
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_words(3, rb->word_ref1, rb->word_ref2);
Problems__handmade_problem(_P_(C16MisplacedRulebookOutcome));
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();
return NEVER_MATCH;
}
}
#line 1856 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1901 "inform7/Chapter 16/Type Checking.w"
if (Specifications__species_is(found, OTHERWISE_SPC)) {
if (block_name == NULL) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__sentence_problem(_P_(C16OtherwiseWithoutIf),
"this is an 'else' or 'otherwise' with no matching 'if' (or 'unless')",
"which must be wrong.");
return NEVER_MATCH;
}
if ((strcmp(block_name, "if") != 0) && (strcmp(block_name, "unless") != 0)) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, block_name);
Problems__handmade_problem(_P_(C16OtherwiseInNonIf));
Problems__issue_problem_segment(
"The 'else' or 'otherwise' here did not make sense inside a "
"'%2' structure: it's provided for 'if' (or 'unless').");
Problems__issue_problem_end();
return NEVER_MATCH;
}
}
}
#line 1857 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1925 "inform7/Chapter 16/Type Checking.w"
if ((Specifications__species_is(found, CASE_SPC)) && (Specifications__get_argc(found) > 0)) {
specification *case_spec = Specifications__get_argument(found, 0);
kind *switch_kind = Code__Frames__Blocks__switch_value_kind();
kind *case_kind = Specifications__evaluates_to(case_spec);
instance *I = Specifications__Values__instance_of_CONSTANT_object_if_any(case_spec);
if (I) case_kind = Data__Instances__kind(I);
LOGIF(MATCHING, "(h.3) switch kind is $u, case kind is $u\n", switch_kind, case_kind);
if ((Specifications__get_kind(case_spec) == NULL) && (I == NULL)) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, switch_kind);
Problems__handmade_problem(_P_(C16CaseValueNonConstant));
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();
return NEVER_MATCH;
}
if (Kinds__compatible(case_kind, switch_kind) != ALWAYS_MATCH) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, case_kind);
Problems__quote_kind(3, switch_kind);
Problems__handmade_problem(_P_(C16CaseValueMismatch));
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();
return NEVER_MATCH;
}
}
}
#line 1858 "inform7/Chapter 16/Type Checking.w"
;
{
#line 1965 "inform7/Chapter 16/Type Checking.w"
if (Specifications__species_is(found, END_BLOCK_SPC)) {
if (block_name == NULL) {
THIS_IS_AN_ORDINARY_PROBLEM;
if (problem_count == 0)
Problems__sentence_problem_with_note(_P_(C16EndWithoutBegin),
"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.");
else problem_count++;
return NEVER_MATCH;
} else {
phrase *ended = RETRIEVE_FROM_SPEC(found, phrase);
if (strcmp(Code__Phrases__TypeData__incipit(ended), block_name) != 0) {
THIS_IS_AN_ORDINARY_PROBLEM;
if (problem_count == 0) {
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, block_name);
Problems__quote_source(3, Code__Frames__Blocks__start_of_current_block());
Problems__handmade_problem(_P_(C16WrongEnd));
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();
} else problem_count++;
return NEVER_MATCH;
}
}
}
}
#line 1859 "inform7/Chapter 16/Type Checking.w"
;
}
#line 485 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__has_invocation_list(found))
{
#line 2002 "inform7/Chapter 16/Type Checking.w"
invocation_list *found_invl = Specifications__invocation_list(found);
invocation *list_of_invocations_to_test[MAX_INVOCATIONS_PER_PHRASE];
int test_count = 0;
int issue_interesting_problems = FALSE;
int current_group = -1;
int invocation_list_passes = FALSE;
phrase *ph;
{
#line 2035 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.1)");
INVOCATION_VARIABLE(inv);
int g = -1, g_max = 0;
for (g = 0; g <= g_max; g++) {
LOOP_THROUGH_INVOCATION_LIST(inv, found_invl) {
int n = Code__Invocations__get_group(inv);
if (n > g_max) g_max = n;
if ((g == n) && (inv->phrase_invoked != phrase_being_compiled))
{
#line 2057 "inform7/Chapter 16/Type Checking.w"
if (test_count >= MAX_INVOCATIONS_PER_PHRASE) internal_error("overrun");
list_of_invocations_to_test[test_count++] = inv;
Code__Invocations__clear_flag(inv, TESTED_INVFLAG);
Code__Invocations__clear_flag(inv, PASSED_INVFLAG);
Code__Invocations__clear_flag(inv, UNPROVEN_INVFLAG);
Code__Invocations__clear_flag(inv, GROSSLY_FAILED_INVFLAG);
Code__Invocations__clear_flag(inv, INTERESTING_PROBLEM_INVFLAG);
}
#line 2043 "inform7/Chapter 16/Type Checking.w"
;
}
LOOP_THROUGH_INVOCATION_LIST(inv, found_invl) {
int n = Code__Invocations__get_group(inv);
if ((g == n) && (inv->phrase_invoked == phrase_being_compiled))
{
#line 2057 "inform7/Chapter 16/Type Checking.w"
if (test_count >= MAX_INVOCATIONS_PER_PHRASE) internal_error("overrun");
list_of_invocations_to_test[test_count++] = inv;
Code__Invocations__clear_flag(inv, TESTED_INVFLAG);
Code__Invocations__clear_flag(inv, PASSED_INVFLAG);
Code__Invocations__clear_flag(inv, UNPROVEN_INVFLAG);
Code__Invocations__clear_flag(inv, GROSSLY_FAILED_INVFLAG);
Code__Invocations__clear_flag(inv, INTERESTING_PROBLEM_INVFLAG);
}
#line 2048 "inform7/Chapter 16/Type Checking.w"
;
}
}
if (test_count != Code__Invocations__Lists__length(found_invl))
internal_error("invocation list broken");
}
#line 2011 "inform7/Chapter 16/Type Checking.w"
;
{
#line 2073 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2)");
LOG_INDENT;
int ref, skip_rest_of_group = FALSE, passed_in_group = 0;
for (ref = 0, current_group = -1; ref<test_count; ref++) {
invocation *inv = list_of_invocations_to_test[ref];
int first_in_group = FALSE, last_in_group = FALSE;
{
#line 2115 "inform7/Chapter 16/Type Checking.w"
if ((ref+1 == test_count) ||
(Code__Invocations__get_group(list_of_invocations_to_test[ref+1]) != Code__Invocations__get_group(inv)))
last_in_group = TRUE;
if ((ref-1 < 0) ||
(Code__Invocations__get_group(list_of_invocations_to_test[ref-1]) != Code__Invocations__get_group(inv)))
first_in_group = TRUE;
}
#line 2079 "inform7/Chapter 16/Type Checking.w"
;
if (first_in_group) {
current_group = Code__Invocations__get_group(inv);
skip_rest_of_group = FALSE; passed_in_group = 0;
LOGIF(MATCHING, "Group G%d begins:\n", current_group);
}
if (skip_rest_of_group) continue;
Code__Phrases__TypeData__parse_within_inv(inv);
{
#line 2149 "inform7/Chapter 16/Type Checking.w"
int invocation_passed = TRUE, with_qualifications = FALSE;
int no_gross_problems_thrown_before = no_gross_problems_thrown;
LOGIF(MATCHING, "(P%d) Trying invocation <$W>: $e\n",
ref, inv->invocation_w1, inv->invocation_w2, inv);
{
#line 2181 "inform7/Chapter 16/Type Checking.w"
ph = inv->phrase_invoked;
if (ph) {
inv->kind_resulting = Code__Phrases__TypeData__get_return_kind(&(ph->type_data));
int arithmetical_phrase = FALSE;
if ((Code__Phrases__TypeData__arithmetic_operation(ph) >= 0) &&
(Code__Phrases__TypeData__arithmetic_operation(ph) < NO_OPERATIONS))
arithmetical_phrase = TRUE;
/* are the arguments of the right kind? */
if (invocation_passed)
{
#line 2214 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.1)");
if (Code__Phrases__TypeData__arithmetic_operation(ph) == TOTAL_OPERATION)
{
#line 2224 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.1.1)");
specification *P = Code__Invocations__get_token_as_parsed(inv, 0);
if (Specifications__Values__is_CONSTANT_construction(P, CON_property)) {
property *prn = Properties__from_specification(P);
if (Properties__is_value_property(prn))
inv->kind_resulting = Properties__Valued__kind(prn);
else {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__sentence_problem(_P_(C16TotalEitherOr),
"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 2244 "inform7/Chapter 16/Type Checking.w"
if (Kinds__get_construct(Specifications__get_kind(P)) == CON_table_column) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__sentence_problem(_P_(C16TotalTableColumn),
"this seems to be an attempt to total up the column of a table",
"whereas it's only legal to use 'total' for properties.");
}
}
invocation_passed = FALSE;
}
#line 2237 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2216 "inform7/Chapter 16/Type Checking.w"
else if (arithmetical_phrase)
{
#line 2256 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.1.2)");
int op_number = Code__Phrases__TypeData__arithmetic_operation(ph);
LOGIF(MATCHING, "(P%d) Arithmetic operation <op-%d>\n", ref, op_number);
specification *L, *R;
kind *kind_wanted, *left_kind, *right_kind, *kind_produced;
{
#line 2270 "inform7/Chapter 16/Type Checking.w"
L = Code__Invocations__get_token_as_parsed(inv, 0);
left_kind = fix_arithmetic_operand(L, depth);
if (Kinds__Dimensions__arithmetic_op_is_unary(op_number)) {
R = NULL; right_kind = NULL;
} else {
R = Code__Invocations__get_token_as_parsed(inv, 1);
right_kind = fix_arithmetic_operand(R, depth);
}
if (((left_kind) && (Kinds__is_quasinumerical(left_kind) == FALSE)) ||
((right_kind) && (Kinds__is_quasinumerical(right_kind) == FALSE)))
kind_produced = NULL;
else
kind_produced = Kinds__Dimensions__arithmetic_on_kinds(left_kind, right_kind, op_number);
kind_wanted = Specifications__get_kind(expected);
}
#line 2262 "inform7/Chapter 16/Type Checking.w"
;
if (kind_produced) inv->kind_resulting = kind_produced;
else
{
#line 2291 "inform7/Chapter 16/Type Checking.w"
if ((left_kind) && (Kinds__eq(left_kind, K_value) == FALSE) &&
(right_kind) && (Kinds__eq(right_kind, K_value) == FALSE)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, L->word_ref1, L->word_ref2);
Problems__quote_words(3, R->word_ref1, R->word_ref2);
Problems__quote_spec(4, Specifications__Values__new_generic_CONSTANT(left_kind));
Problems__quote_spec(5, Specifications__Values__new_generic_CONSTANT(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__handmade_problem(_P_(C16BadArithmetic));
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();
}
}
invocation_passed = FALSE;
}
#line 2265 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2217 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2191 "inform7/Chapter 16/Type Checking.w"
;
if (invocation_passed)
{
#line 2327 "inform7/Chapter 16/Type Checking.w"
if (!arithmetical_phrase) {
LOG_STAGE("(i.2.2)");
int i, exit_at_once = FALSE;
for (i=0; i<Code__Invocations__get_number_tokens(inv); i++) {
LOGIF(MATCHING, "(i.2.2) trying argument %d (prior to this, passed: %d)\n",
i, invocation_passed);
specification ith_token = *(Code__Invocations__get_token_as_parsed(inv, i));
Code__Invocations__set_token_check_to_do(inv, i, NULL);
{
#line 2351 "inform7/Chapter 16/Type Checking.w"
specification *ith_spec = ph->type_data.token_sequence[i].to_match;
if ((ph->type_data.token_sequence[i].name_of_a_kind) && (invocation_passed))
{
#line 2423 "inform7/Chapter 16/Type Checking.w"
invocation_passed = FALSE;
LOGIF(MATCHING, "(i.2.2) thinking about reparsing: $S\n", &ith_token);
if ((Specifications__is_UNKNOWN(&ith_token)) ||
(Specifications__species_is(&ith_token, DESCRIPTION_SPC)) ||
(Specifications__Values__is_actual_CONSTANT_construction(&ith_token, CON_property)) ||
(Specifications__Values__is_generic_CONSTANT(&ith_token)) ||
((Code__Phrases__TypeData__is_a_let_assignment(ph) == FALSE) &&
(Specifications__species_is(&ith_token, PHRASE_TO_DECIDE_VALUE_SPC)))) {
int w1 = ith_token.word_ref1, w2 = ith_token.word_ref2;
kind *K = NULL;
specification *reparsed = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, w1, w2, NULL, NULL)) reparsed = most_recent_result_p;
if (Specifications__Values__is_generic_CONSTANT(reparsed))
K = Specifications__get_kind(reparsed);
if ((K == NULL) && (parse_nt_against_word_range(k_kind_NTM, w1, w2, NULL, NULL))) K = most_recent_result_p;
if (K == NULL) {
if ((parse_nt_against_word_range(value_property_name_NTM, w1, w2, NULL, NULL)) &&
(Properties__Valued__coincides_with_kind(most_recent_result_p)))
K = Properties__Valued__kind(most_recent_result_p);
}
LOGIF(MATCHING, "(i.2.2) reparsed as: $u\n", K);
if ((K) && (Specifications__Values__is_generic_CONSTANT(ith_spec))) {
kind *ikind = Specifications__get_kind(ith_spec);
if (Kinds__compatible(K, ikind) == ALWAYS_MATCH) {
LOGIF(MATCHING, "(i.2.2) allows name-of token: $S\n", reparsed);
ith_token = *reparsed;
invocation_passed = TRUE;
} else {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_kind_of(3, ith_spec);
Problems__handmade_problem(_P_(C16NameOfKindMismatch));
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();
}
}
}
}
}
#line 2353 "inform7/Chapter 16/Type Checking.w"
else {
int save_kcm = kind_checker_mode;
kind_checker_mode = MATCH_KIND_VARIABLES_AS_UNIVERSAL;
kind *create = NULL;
switch(typecheck_recursive(&ith_token, ith_spec, 2, depth+1, &create)) {
case NEVER_MATCH:
LOGIF(MATCHING, "(i.2.2) on $S failed at token %d\n", found, i);
invocation_passed = FALSE;
if (problems_issued_during_typechecking()) exit_at_once = TRUE;
break;
case SOMETIMES_MATCH:
LOGIF(MATCHING, "(i.2.2) on $S qualified at token %d\n", found, i);
Code__Invocations__set_token_check_to_do(inv, i, ith_spec);
with_qualifications = TRUE;
break;
}
kind_checker_mode = save_kcm;
if (create) {
if ((depth > 1) && (Code__Phrases__TypeData__is_a_let_assignment(ph))) {
THIS_IS_AN_ORDINARY_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C16LetCreatedInIf));
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();
}
}
Code__Invocations__set_token_variable_kind(inv, i, create);
}
}
}
#line 2335 "inform7/Chapter 16/Type Checking.w"
;
if (exit_at_once) break;
if (Specifications__test_flag(&ith_token, COERCED_SPFLAG)) {
LOGIF(MATCHING, "(i.2.2) duplicates $S\n", &ith_token);
Code__Invocations__set_token_as_parsed(inv, i, Specifications__copy(&ith_token));
} else {
LOGIF(MATCHING, "(i.2.2) declines to duplicate $S\n", &ith_token);
*(Code__Invocations__get_token_as_parsed(inv, i)) = ith_token;
}
}
if (invocation_passed) LOGIF(MATCHING, "(i.2.2) argument type matching passed\n");
}
}
#line 2192 "inform7/Chapter 16/Type Checking.w"
;
if (invocation_passed)
{
#line 2474 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.3)");
int exit_at_once = FALSE;
kind_variable_declaration *kvd_marker = LAST_OBJECT(kind_variable_declaration);
if (Code__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, "(i.2.3) prototype check pass %d\n", pass);
if (Log__Aspects__on(MATCHING_DA)) Kinds__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<Code__Invocations__get_number_tokens(inv); i++) {
if (ph->type_data.token_sequence[i].token_kind) {
specification *token_spec = Code__Invocations__get_token_as_parsed(inv, i);
kind *kind_read = Specifications__evaluates_to(token_spec);
if ((ph->type_data.token_sequence[i].name_of_a_kind) &&
(Specifications__species_is(token_spec, DESCRIPTION_SPC)))
kind_read = Specifications__Conditions__get_described_kind(token_spec);
LOGIF(MATCHING, "Token %d: $S: kind $u: template $u\n", i,
token_spec, kind_read, ph->type_data.token_sequence[i].token_kind);
switch(Kinds__compatible(kind_read, ph->type_data.token_sequence[i].token_kind)) {
case NEVER_MATCH:
LOGIF(MATCHING, "(i.2.3) failed at token %d\n", i);
invocation_passed = FALSE;
if (problems_issued_during_typechecking()) exit_at_once = TRUE;
break;
case SOMETIMES_MATCH:
best_result = SOMETIMES_MATCH;
/* we won't use |with_qualifications| -- we don't know exactly what they are */
LOGIF(MATCHING, "(i.2.3) 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) && (invocation_passed)) {
LOGIF(MATCHING, "(i.2.3) 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 (invocation_passed) inv->kind_variable_declarations = most_recent_interpretation;
most_recent_interpretation = save_most_recent_interpretation;
}
if (Kinds__contains(inv->kind_resulting, CON_KIND_VARIABLE)) {
int changed = FALSE;
kind *K = Kinds__substitute(inv->kind_resulting, NULL, &changed);
if (changed) {
LOGIF(MATCHING, "(i.2.3) amended kind returned to $u\n", K);
inv->kind_resulting = K;
} else
{
#line 2545 "inform7/Chapter 16/Type Checking.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__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();
return NEVER_MATCH;
}
#line 2539 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 2193 "inform7/Chapter 16/Type Checking.w"
;
if (invocation_passed)
{
#line 2583 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.4)");
if (Code__Phrases__TypeData__is_assignment_phrase(ph)) {
specification *target = Code__Invocations__get_token_as_parsed(inv, 0);
specification *new_value = Code__Invocations__get_token_as_parsed(inv, 1);
specification *target_spec = ph->type_data.token_sequence[0].to_match;
specification *new_value_spec = ph->type_data.token_sequence[1].to_match;
local_variable *lvar = Specifications__Storage__get_local_variable_if_any(target);
if ((lvar) && (Code__LocalVariables__protected(lvar))) return NEVER_MATCH;
if (Kinds__le(Specifications__get_kind(target_spec), K_object))
{
#line 2608 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.4.1)");
instance *target_wo = Specifications__Values__instance_of_CONSTANT_object_if_any(target);
property *prn = NULL;
int make_check = FALSE;
if (Kinds__eq(Specifications__get_kind(new_value_spec), K_value))
{
#line 2633 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.4.1a)");
instance *I = Specifications__Values__get_named_constant_if_any(new_value);
if (I == NULL) invocation_passed = FALSE;
else {
prn = Kinds__get_coinciding_property(Data__Instances__kind(I));
if (prn == NULL) invocation_passed = FALSE;
else make_check = TRUE;
}
}
#line 2613 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__Values__is_CONSTANT_construction(new_value_spec, CON_property))
{
#line 2656 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.4.1b)");
if (Specifications__Values__is_CONSTANT_construction(new_value, CON_property))
prn = Properties__from_specification(new_value);
else if (Specifications__Conditions__number_of_adjectives_applied_to(new_value) == 1) {
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(Specifications__Conditions__first_adjective_list_entry(new_value));
if (Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(aph))
prn = Kinds__get_coinciding_property(Data__Instances__kind(Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(aph)));
else if (Semantics__Adjectives__Phrases__has_EORP_meaning(aph))
prn = Semantics__Adjectives__Phrases__has_EORP_meaning(aph);
}
make_check = TRUE;
}
#line 2615 "inform7/Chapter 16/Type Checking.w"
;
if (make_check)
{
#line 2684 "inform7/Chapter 16/Type Checking.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_words(2, target->word_ref1, target->word_ref2);
Problems__quote_words(3, new_value->word_ref1, new_value->word_ref2);
Problems__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(Data__Instances__as_subject(target_wo), prn, TRUE) == NULL)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, target->word_ref1, target->word_ref2);
Problems__quote_property(3, prn);
Problems__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 2617 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2595 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__family_is(target_spec, STORAGE_FMY))
{
#line 2718 "inform7/Chapter 16/Type Checking.w"
kind *kind_wanted, *kind_found;
LOGIF(MATCHING, "Check assignment of $S to $S\n", new_value, target);
switch(Specifications__Storage__get_storage_form(target_spec)) {
case LOCAL_VARIABLE_SPC: Problems__quote_text(6, "the name of"); break;
case PROPERTY_VALUE_SPC: Problems__quote_text(6, "a property whose kind of value is"); break;
case NONLOCAL_VARIABLE_SPC: Problems__quote_text(6, "a variable whose kind of value is"); break;
case TABLE_ENTRY_SPC: Problems__quote_text(6, "a table entry whose kind of value is"); break;
case LIST_ENTRY_SPC: 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__evaluates_to(target);
kind_found = Specifications__evaluates_to(new_value);
invocation_list *new_invl = Specifications__invocation_list(new_value);
if (new_invl) {
INVOCATION_VARIABLE(new_inv);
LOOP_THROUGH_INVOCATION_LIST(new_inv, new_invl)
if (Code__Invocations__test_flag(new_inv, PASSED_INVFLAG)) break;
if (new_inv) kind_found = new_inv->kind_resulting;
}
LOGIF(MATCHING, "Kinds found: $u, wanted: $u\n", kind_found, kind_wanted);
if (((Kinds__eq(kind_wanted, K_understanding)) &&
(Kinds__eq(kind_found, K_understanding) == FALSE))
|| (Kinds__compatible(kind_found, kind_wanted) == NEVER_MATCH)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, target->word_ref1, target->word_ref2);
Problems__quote_kind(3, Specifications__evaluates_to(target));
Problems__quote_words(4, new_value->word_ref1, new_value->word_ref2);
Problems__quote_kind(5, Specifications__evaluates_to(new_value));
Problems__handmade_problem(_P_(C16ChangeToWrongValue));
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 2598 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 2194 "inform7/Chapter 16/Type Checking.w"
;
/* if this evaluates something, is it a value of the right kind? */
if (invocation_passed)
{
#line 2772 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.5)");
if (Specifications__species_is(found, PHRASE_TO_DECIDE_VALUE_SPC)) {
kind *kind_needed = Specifications__get_kind(expected);
int outcome_test = ALWAYS_MATCH;
if (kind_needed) {
LOGIF(MATCHING, "(P%d) Checking returned $u against desired $u\n",
ref, inv->kind_resulting, kind_needed);
outcome_test = Kinds__compatible(inv->kind_resulting, kind_needed);
}
switch (outcome_test) {
case NEVER_MATCH: invocation_passed = FALSE; break;
case SOMETIMES_MATCH: best_result = SOMETIMES_MATCH; break;
}
}
}
#line 2197 "inform7/Chapter 16/Type Checking.w"
;
/* are there any special rules about invoking this phrase? */
if (invocation_passed)
{
#line 2791 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.6)");
if ((invocation_passed) && (inv->phrase_options_invoked)) {
int cso = Code__Phrases__Options__parse_invoked_options(
inv, (problem_threshold >= 2)?TRUE:FALSE);
if (cso == FALSE) invocation_passed = FALSE;
}
}
#line 2200 "inform7/Chapter 16/Type Checking.w"
;
if (invocation_passed)
{
#line 2814 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.7)");
if ((Code__Phrases__TypeData__is_a_say_phrase(ph)) &&
(Code__Invocations__get_number_tokens(inv) == 1) &&
(Specifications__Storage__get_storage_form(Code__Invocations__get_token_as_parsed(inv, 0)) == PROPERTY_VALUE_SPC)) {
Specifications__set_flag(Code__Invocations__get_token_as_parsed(inv, 0), RECORD_AS_SELF_SPFLAG);
Code__Invocations__set_flag(inv, SAVE_SELF_INVFLAG);
}
}
#line 2201 "inform7/Chapter 16/Type Checking.w"
;
if (invocation_passed)
{
#line 2830 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(1.2.8)");
if (ph) {
char *required = Code__Phrases__TypeData__only_in(ph);
if (required) {
if (strcmp(required, "loop") == 0) {
LOGIF(MATCHING, "Required to be inside loop body\n");
if (Code__Frames__Blocks__inside_a_loop_body() == FALSE) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C16CantUseOutsideLoop));
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 = Code__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__handmade_problem(_P_(C16CantUseOutsideStructure));
Problems__issue_problem_segment(
"%1 makes sense only inside a '%2' block.");
Problems__issue_problem_end();
}
}
}
}
}
}
#line 2202 "inform7/Chapter 16/Type Checking.w"
;
if ((invocation_passed) && (no_deprecated_features))
{
#line 2866 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(1.2.9)");
if ((ph) && (ph->type_data.now_deprecated)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__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 2204 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 2155 "inform7/Chapter 16/Type Checking.w"
;
Code__Invocations__set_flag(inv, TESTED_INVFLAG);
if (invocation_passed) {
Code__Invocations__set_flag(inv, PASSED_INVFLAG);
if (with_qualifications) Code__Invocations__set_flag(inv, UNPROVEN_INVFLAG);
} else if (no_gross_problems_thrown > no_gross_problems_thrown_before)
Code__Invocations__set_flag(inv, GROSSLY_FAILED_INVFLAG);
}
#line 2089 "inform7/Chapter 16/Type Checking.w"
;
{
#line 2125 "inform7/Chapter 16/Type Checking.w"
char *verdict = "Failed";
if (Code__Invocations__test_flag(inv, PASSED_INVFLAG)) verdict = "Passed";
if (Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG)) verdict = "Passed (with qualifications)";
if (Code__Invocations__test_flag(inv, GROSSLY_FAILED_INVFLAG)) verdict = "Failed grossly";
LOGIF(MATCHING, "%s: P%d: $e\n", verdict, ref, inv);
}
#line 2090 "inform7/Chapter 16/Type Checking.w"
;
if (Code__Invocations__test_flag(inv, PASSED_INVFLAG)) {
invocation_list_passes = TRUE;
passed_in_group++;
if ((last_in_group) || (Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG) == FALSE)) {
LOGIF(MATCHING, "Group G%d passed%s\n", current_group,
(Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG))?" subject to run-time checking":"");
skip_rest_of_group = TRUE;
}
} else {
if ((last_in_group) && (passed_in_group == 0)) {
LOGIF(MATCHING, "Group G%d failed\n", current_group);
invocation_list_passes = FALSE; /* to force error */
break;
}
}
if (problems_issued_during_typechecking()) break; /* to prevent duplication of problem messages */
}
LOG_OUTDENT;
{
#line 2134 "inform7/Chapter 16/Type Checking.w"
int g = -1, i;
for (i=0; i<test_count; i++) {
invocation *inv = list_of_invocations_to_test[i];
if (g != Code__Invocations__get_group(inv)) { g = Code__Invocations__get_group(inv); LOGIF(MATCHING, "| "); }
if (Code__Invocations__test_flag(inv, TESTED_INVFLAG) == FALSE) { LOGIF(MATCHING, "- "); }
else if (Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG)) { LOGIF(MATCHING, "? "); }
else if (Code__Invocations__test_flag(inv, GROSSLY_FAILED_INVFLAG)) { LOGIF(MATCHING, "g "); }
else if (Code__Invocations__test_flag(inv, PASSED_INVFLAG)) { LOGIF(MATCHING, "p "); }
else { LOGIF(MATCHING, "f "); }
}
LOGIF(MATCHING, "|\n");
}
#line 2110 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2012 "inform7/Chapter 16/Type Checking.w"
;
if (problems_issued_during_typechecking()) return NEVER_MATCH;
if (invocation_list_passes)
{
#line 2885 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.3)");
{
#line 2909 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.3.1)");
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_INVOCATION_LIST(inv, Specifications__invocation_list(found)) {
if ((Code__Invocations__test_flag(inv, PASSED_INVFLAG)) ||
(Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG))) {
int N = Code__Invocations__get_number_tokens(inv);
int i;
for (i=0; i<N; i++) {
kind *K = Code__Invocations__get_token_variable_kind(inv, i);
if (K) {
if ((i == 0) && (N >= 2) && (Kinds__eq(K, K_value)) &&
(Code__Phrases__TypeData__is_a_let_assignment(inv->phrase_invoked)))
{
#line 2941 "inform7/Chapter 16/Type Checking.w"
specification *val = Code__Invocations__get_token_as_parsed(inv, i);
int w1 = val->word_ref1, w2 = val->word_ref2;
specification *initial_value = Code__Invocations__get_token_as_parsed(inv, 1);
specification *iv_spec = inv->phrase_invoked->type_data.token_sequence[1].to_match;
if (initial_value)
{
#line 2968 "inform7/Chapter 16/Type Checking.w"
kind *seems_to_be = NULL;
if ((Specifications__Values__is_generic_CONSTANT(iv_spec)) &&
(Specifications__Values__is_actual_CONSTANT(initial_value))) {
kind *K = Specifications__get_kind(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) &&
(Specifications__Values__is_generic_CONSTANT(initial_value))) {
seems_to_be = Specifications__get_kind(initial_value);
}
if (seems_to_be == NULL)
seems_to_be = Specifications__get_kind_referred_to(initial_value);
LOGIF(LOCAL_VARIABLES, "New variable $W from $S ($S) seems to be: $u\n",
w1, w2, initial_value, iv_spec, seems_to_be);
if (seems_to_be == NULL)
{
#line 3000 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, initial_value->word_ref1, initial_value->word_ref2);
Problems__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 2986 "inform7/Chapter 16/Type Checking.w"
;
if ((Kinds__get_construct(seems_to_be) == CON_list_of) &&
(Kinds__eq(Kinds__unary_construction_material(seems_to_be), K_value)))
{
#line 3015 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
int pc = problem_count;
Data__Lists__check_one(initial_value->word_ref1);
if (pc == problem_count) {
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C16CantLetEmptyList));
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 2990 "inform7/Chapter 16/Type Checking.w"
;
if (Kinds__definite(seems_to_be) == FALSE)
{
#line 3033 "inform7/Chapter 16/Type Checking.w"
LOGIF(MATCHING, "Unable to store the kind: $u\n", K);
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__sentence_problem(_P_(C16BadLocalKOV),
"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 2992 "inform7/Chapter 16/Type Checking.w"
;
if (Kinds__le(seems_to_be, K_object)) K = K_object;
else K = seems_to_be;
LOGIF(LOCAL_VARIABLES, "Inferred the kind: $u\n", K);
}
#line 2946 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2921 "inform7/Chapter 16/Type Checking.w"
;
int changed = FALSE;
K = Kinds__substitute(K, NULL, &changed);
if (changed) LOGIF(MATCHING, "(i.3.1) Local var amended to $u\n", K);
Code__Invocations__set_token_variable_kind(inv, i, K);
}
}
}
}
}
#line 2886 "inform7/Chapter 16/Type Checking.w"
;
{
#line 3064 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.3.2)");
invocation_list *invl = Code__Invocations__Lists__new();
int nfi = 0, nfi_group = -1, number_ambiguity = FALSE;
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_INVOCATION_LIST(inv, found_invl) {
if (Code__Invocations__test_flag(inv, PASSED_INVFLAG)) {
{
#line 3118 "inform7/Chapter 16/Type Checking.w"
phrase *ph = inv->phrase_invoked;
if (ph) {
int n = ph->ph_documentation_symbol_wn;
if (n >= 0)
Index__doc_mark_used(Text__word_raw_text(n), inv->invocation_w1);
}
}
#line 3071 "inform7/Chapter 16/Type Checking.w"
;
int nti = Code__Invocations__get_number_tokens(inv);
if (nfi_group != Code__Invocations__get_group(inv)) {
nfi = nti;
nfi_group = Code__Invocations__get_group(inv);
} else {
if (nfi != nti) number_ambiguity = TRUE;
}
Code__Invocations__Lists__add(invl, inv);
}
}
if (number_ambiguity)
{
#line 3097 "inform7/Chapter 16/Type Checking.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C16UnequalValueAmbiguity));
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 3083 "inform7/Chapter 16/Type Checking.w"
;
Specifications__set_invocation_list(found, invl);
found_invl = invl;
}
#line 2887 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2014 "inform7/Chapter 16/Type Checking.w"
else
{
#line 3139 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.4)");
THIS_IS_AN_ORDINARY_PROBLEM;
if (current_group < 0) return NEVER_MATCH; /* just in case |found| had an empty invocation list */
LOGIF(MATCHING, "All invocations failed: issuing problem\n$E", found_invl);
invocation *first_inv_in_group = NULL;
invocation *first_failing_interestingly = NULL;
invocation *first_not_failing_grossly = NULL;
int say_w1 = -1, say_w2 = -1;
int list_includes_lets = FALSE;
int nongross_count = 0;
{
#line 3169 "inform7/Chapter 16/Type Checking.w"
int ref;
for (ref=0; ref<test_count; ref++) {
invocation *inv = list_of_invocations_to_test[ref];
if (Code__Invocations__get_group(inv) == current_group) {
if ((Code__Invocations__test_flag(inv, INTERESTING_PROBLEM_INVFLAG)) &&
(first_failing_interestingly == NULL)) first_failing_interestingly = inv;
ph = inv->phrase_invoked;
if (Code__Phrases__TypeData__is_a_let_assignment(ph)) list_includes_lets = TRUE;
if (first_inv_in_group == NULL) first_inv_in_group = inv;
if (Code__Invocations__test_flag(inv, GROSSLY_FAILED_INVFLAG) == FALSE) {
first_not_failing_grossly = inv;
if (Code__Phrases__TypeData__is_a_say_X_phrase(&(ph->type_data))) {
say_w1 = inv->invocation_w1; say_w2 = inv->invocation_w2;
}
nongross_count++;
}
}
}
}
#line 3151 "inform7/Chapter 16/Type Checking.w"
;
invocation *most_likely_to_have_been_intended = NULL;
{
#line 3191 "inform7/Chapter 16/Type Checking.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 3154 "inform7/Chapter 16/Type Checking.w"
;
if (first_failing_interestingly)
{
#line 3203 "inform7/Chapter 16/Type Checking.w"
issue_interesting_problems = TRUE;
invocation *inv = first_failing_interestingly;
int ref = 0; /* will be shown in the debugging log as P0 now */
{
#line 2149 "inform7/Chapter 16/Type Checking.w"
int invocation_passed = TRUE, with_qualifications = FALSE;
int no_gross_problems_thrown_before = no_gross_problems_thrown;
LOGIF(MATCHING, "(P%d) Trying invocation <$W>: $e\n",
ref, inv->invocation_w1, inv->invocation_w2, inv);
{
#line 2181 "inform7/Chapter 16/Type Checking.w"
ph = inv->phrase_invoked;
if (ph) {
inv->kind_resulting = Code__Phrases__TypeData__get_return_kind(&(ph->type_data));
int arithmetical_phrase = FALSE;
if ((Code__Phrases__TypeData__arithmetic_operation(ph) >= 0) &&
(Code__Phrases__TypeData__arithmetic_operation(ph) < NO_OPERATIONS))
arithmetical_phrase = TRUE;
/* are the arguments of the right kind? */
if (invocation_passed)
{
#line 2214 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.1)");
if (Code__Phrases__TypeData__arithmetic_operation(ph) == TOTAL_OPERATION)
{
#line 2224 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.1.1)");
specification *P = Code__Invocations__get_token_as_parsed(inv, 0);
if (Specifications__Values__is_CONSTANT_construction(P, CON_property)) {
property *prn = Properties__from_specification(P);
if (Properties__is_value_property(prn))
inv->kind_resulting = Properties__Valued__kind(prn);
else {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__sentence_problem(_P_(C16TotalEitherOr),
"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 2244 "inform7/Chapter 16/Type Checking.w"
if (Kinds__get_construct(Specifications__get_kind(P)) == CON_table_column) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__sentence_problem(_P_(C16TotalTableColumn),
"this seems to be an attempt to total up the column of a table",
"whereas it's only legal to use 'total' for properties.");
}
}
invocation_passed = FALSE;
}
#line 2237 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2216 "inform7/Chapter 16/Type Checking.w"
else if (arithmetical_phrase)
{
#line 2256 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.1.2)");
int op_number = Code__Phrases__TypeData__arithmetic_operation(ph);
LOGIF(MATCHING, "(P%d) Arithmetic operation <op-%d>\n", ref, op_number);
specification *L, *R;
kind *kind_wanted, *left_kind, *right_kind, *kind_produced;
{
#line 2270 "inform7/Chapter 16/Type Checking.w"
L = Code__Invocations__get_token_as_parsed(inv, 0);
left_kind = fix_arithmetic_operand(L, depth);
if (Kinds__Dimensions__arithmetic_op_is_unary(op_number)) {
R = NULL; right_kind = NULL;
} else {
R = Code__Invocations__get_token_as_parsed(inv, 1);
right_kind = fix_arithmetic_operand(R, depth);
}
if (((left_kind) && (Kinds__is_quasinumerical(left_kind) == FALSE)) ||
((right_kind) && (Kinds__is_quasinumerical(right_kind) == FALSE)))
kind_produced = NULL;
else
kind_produced = Kinds__Dimensions__arithmetic_on_kinds(left_kind, right_kind, op_number);
kind_wanted = Specifications__get_kind(expected);
}
#line 2262 "inform7/Chapter 16/Type Checking.w"
;
if (kind_produced) inv->kind_resulting = kind_produced;
else
{
#line 2291 "inform7/Chapter 16/Type Checking.w"
if ((left_kind) && (Kinds__eq(left_kind, K_value) == FALSE) &&
(right_kind) && (Kinds__eq(right_kind, K_value) == FALSE)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, L->word_ref1, L->word_ref2);
Problems__quote_words(3, R->word_ref1, R->word_ref2);
Problems__quote_spec(4, Specifications__Values__new_generic_CONSTANT(left_kind));
Problems__quote_spec(5, Specifications__Values__new_generic_CONSTANT(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__handmade_problem(_P_(C16BadArithmetic));
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();
}
}
invocation_passed = FALSE;
}
#line 2265 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2217 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2191 "inform7/Chapter 16/Type Checking.w"
;
if (invocation_passed)
{
#line 2327 "inform7/Chapter 16/Type Checking.w"
if (!arithmetical_phrase) {
LOG_STAGE("(i.2.2)");
int i, exit_at_once = FALSE;
for (i=0; i<Code__Invocations__get_number_tokens(inv); i++) {
LOGIF(MATCHING, "(i.2.2) trying argument %d (prior to this, passed: %d)\n",
i, invocation_passed);
specification ith_token = *(Code__Invocations__get_token_as_parsed(inv, i));
Code__Invocations__set_token_check_to_do(inv, i, NULL);
{
#line 2351 "inform7/Chapter 16/Type Checking.w"
specification *ith_spec = ph->type_data.token_sequence[i].to_match;
if ((ph->type_data.token_sequence[i].name_of_a_kind) && (invocation_passed))
{
#line 2423 "inform7/Chapter 16/Type Checking.w"
invocation_passed = FALSE;
LOGIF(MATCHING, "(i.2.2) thinking about reparsing: $S\n", &ith_token);
if ((Specifications__is_UNKNOWN(&ith_token)) ||
(Specifications__species_is(&ith_token, DESCRIPTION_SPC)) ||
(Specifications__Values__is_actual_CONSTANT_construction(&ith_token, CON_property)) ||
(Specifications__Values__is_generic_CONSTANT(&ith_token)) ||
((Code__Phrases__TypeData__is_a_let_assignment(ph) == FALSE) &&
(Specifications__species_is(&ith_token, PHRASE_TO_DECIDE_VALUE_SPC)))) {
int w1 = ith_token.word_ref1, w2 = ith_token.word_ref2;
kind *K = NULL;
specification *reparsed = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, w1, w2, NULL, NULL)) reparsed = most_recent_result_p;
if (Specifications__Values__is_generic_CONSTANT(reparsed))
K = Specifications__get_kind(reparsed);
if ((K == NULL) && (parse_nt_against_word_range(k_kind_NTM, w1, w2, NULL, NULL))) K = most_recent_result_p;
if (K == NULL) {
if ((parse_nt_against_word_range(value_property_name_NTM, w1, w2, NULL, NULL)) &&
(Properties__Valued__coincides_with_kind(most_recent_result_p)))
K = Properties__Valued__kind(most_recent_result_p);
}
LOGIF(MATCHING, "(i.2.2) reparsed as: $u\n", K);
if ((K) && (Specifications__Values__is_generic_CONSTANT(ith_spec))) {
kind *ikind = Specifications__get_kind(ith_spec);
if (Kinds__compatible(K, ikind) == ALWAYS_MATCH) {
LOGIF(MATCHING, "(i.2.2) allows name-of token: $S\n", reparsed);
ith_token = *reparsed;
invocation_passed = TRUE;
} else {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_kind_of(3, ith_spec);
Problems__handmade_problem(_P_(C16NameOfKindMismatch));
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();
}
}
}
}
}
#line 2353 "inform7/Chapter 16/Type Checking.w"
else {
int save_kcm = kind_checker_mode;
kind_checker_mode = MATCH_KIND_VARIABLES_AS_UNIVERSAL;
kind *create = NULL;
switch(typecheck_recursive(&ith_token, ith_spec, 2, depth+1, &create)) {
case NEVER_MATCH:
LOGIF(MATCHING, "(i.2.2) on $S failed at token %d\n", found, i);
invocation_passed = FALSE;
if (problems_issued_during_typechecking()) exit_at_once = TRUE;
break;
case SOMETIMES_MATCH:
LOGIF(MATCHING, "(i.2.2) on $S qualified at token %d\n", found, i);
Code__Invocations__set_token_check_to_do(inv, i, ith_spec);
with_qualifications = TRUE;
break;
}
kind_checker_mode = save_kcm;
if (create) {
if ((depth > 1) && (Code__Phrases__TypeData__is_a_let_assignment(ph))) {
THIS_IS_AN_ORDINARY_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C16LetCreatedInIf));
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();
}
}
Code__Invocations__set_token_variable_kind(inv, i, create);
}
}
}
#line 2335 "inform7/Chapter 16/Type Checking.w"
;
if (exit_at_once) break;
if (Specifications__test_flag(&ith_token, COERCED_SPFLAG)) {
LOGIF(MATCHING, "(i.2.2) duplicates $S\n", &ith_token);
Code__Invocations__set_token_as_parsed(inv, i, Specifications__copy(&ith_token));
} else {
LOGIF(MATCHING, "(i.2.2) declines to duplicate $S\n", &ith_token);
*(Code__Invocations__get_token_as_parsed(inv, i)) = ith_token;
}
}
if (invocation_passed) LOGIF(MATCHING, "(i.2.2) argument type matching passed\n");
}
}
#line 2192 "inform7/Chapter 16/Type Checking.w"
;
if (invocation_passed)
{
#line 2474 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.3)");
int exit_at_once = FALSE;
kind_variable_declaration *kvd_marker = LAST_OBJECT(kind_variable_declaration);
if (Code__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, "(i.2.3) prototype check pass %d\n", pass);
if (Log__Aspects__on(MATCHING_DA)) Kinds__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<Code__Invocations__get_number_tokens(inv); i++) {
if (ph->type_data.token_sequence[i].token_kind) {
specification *token_spec = Code__Invocations__get_token_as_parsed(inv, i);
kind *kind_read = Specifications__evaluates_to(token_spec);
if ((ph->type_data.token_sequence[i].name_of_a_kind) &&
(Specifications__species_is(token_spec, DESCRIPTION_SPC)))
kind_read = Specifications__Conditions__get_described_kind(token_spec);
LOGIF(MATCHING, "Token %d: $S: kind $u: template $u\n", i,
token_spec, kind_read, ph->type_data.token_sequence[i].token_kind);
switch(Kinds__compatible(kind_read, ph->type_data.token_sequence[i].token_kind)) {
case NEVER_MATCH:
LOGIF(MATCHING, "(i.2.3) failed at token %d\n", i);
invocation_passed = FALSE;
if (problems_issued_during_typechecking()) exit_at_once = TRUE;
break;
case SOMETIMES_MATCH:
best_result = SOMETIMES_MATCH;
/* we won't use |with_qualifications| -- we don't know exactly what they are */
LOGIF(MATCHING, "(i.2.3) 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) && (invocation_passed)) {
LOGIF(MATCHING, "(i.2.3) 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 (invocation_passed) inv->kind_variable_declarations = most_recent_interpretation;
most_recent_interpretation = save_most_recent_interpretation;
}
if (Kinds__contains(inv->kind_resulting, CON_KIND_VARIABLE)) {
int changed = FALSE;
kind *K = Kinds__substitute(inv->kind_resulting, NULL, &changed);
if (changed) {
LOGIF(MATCHING, "(i.2.3) amended kind returned to $u\n", K);
inv->kind_resulting = K;
} else
{
#line 2545 "inform7/Chapter 16/Type Checking.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__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();
return NEVER_MATCH;
}
#line 2539 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 2193 "inform7/Chapter 16/Type Checking.w"
;
if (invocation_passed)
{
#line 2583 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.4)");
if (Code__Phrases__TypeData__is_assignment_phrase(ph)) {
specification *target = Code__Invocations__get_token_as_parsed(inv, 0);
specification *new_value = Code__Invocations__get_token_as_parsed(inv, 1);
specification *target_spec = ph->type_data.token_sequence[0].to_match;
specification *new_value_spec = ph->type_data.token_sequence[1].to_match;
local_variable *lvar = Specifications__Storage__get_local_variable_if_any(target);
if ((lvar) && (Code__LocalVariables__protected(lvar))) return NEVER_MATCH;
if (Kinds__le(Specifications__get_kind(target_spec), K_object))
{
#line 2608 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.4.1)");
instance *target_wo = Specifications__Values__instance_of_CONSTANT_object_if_any(target);
property *prn = NULL;
int make_check = FALSE;
if (Kinds__eq(Specifications__get_kind(new_value_spec), K_value))
{
#line 2633 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.4.1a)");
instance *I = Specifications__Values__get_named_constant_if_any(new_value);
if (I == NULL) invocation_passed = FALSE;
else {
prn = Kinds__get_coinciding_property(Data__Instances__kind(I));
if (prn == NULL) invocation_passed = FALSE;
else make_check = TRUE;
}
}
#line 2613 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__Values__is_CONSTANT_construction(new_value_spec, CON_property))
{
#line 2656 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.4.1b)");
if (Specifications__Values__is_CONSTANT_construction(new_value, CON_property))
prn = Properties__from_specification(new_value);
else if (Specifications__Conditions__number_of_adjectives_applied_to(new_value) == 1) {
adjectival_phrase *aph = Specifications__Conditions__get_adjective_from_list_entry(Specifications__Conditions__first_adjective_list_entry(new_value));
if (Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(aph))
prn = Kinds__get_coinciding_property(Data__Instances__kind(Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(aph)));
else if (Semantics__Adjectives__Phrases__has_EORP_meaning(aph))
prn = Semantics__Adjectives__Phrases__has_EORP_meaning(aph);
}
make_check = TRUE;
}
#line 2615 "inform7/Chapter 16/Type Checking.w"
;
if (make_check)
{
#line 2684 "inform7/Chapter 16/Type Checking.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_words(2, target->word_ref1, target->word_ref2);
Problems__quote_words(3, new_value->word_ref1, new_value->word_ref2);
Problems__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(Data__Instances__as_subject(target_wo), prn, TRUE) == NULL)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, target->word_ref1, target->word_ref2);
Problems__quote_property(3, prn);
Problems__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 2617 "inform7/Chapter 16/Type Checking.w"
;
}
#line 2595 "inform7/Chapter 16/Type Checking.w"
;
if (Specifications__family_is(target_spec, STORAGE_FMY))
{
#line 2718 "inform7/Chapter 16/Type Checking.w"
kind *kind_wanted, *kind_found;
LOGIF(MATCHING, "Check assignment of $S to $S\n", new_value, target);
switch(Specifications__Storage__get_storage_form(target_spec)) {
case LOCAL_VARIABLE_SPC: Problems__quote_text(6, "the name of"); break;
case PROPERTY_VALUE_SPC: Problems__quote_text(6, "a property whose kind of value is"); break;
case NONLOCAL_VARIABLE_SPC: Problems__quote_text(6, "a variable whose kind of value is"); break;
case TABLE_ENTRY_SPC: Problems__quote_text(6, "a table entry whose kind of value is"); break;
case LIST_ENTRY_SPC: 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__evaluates_to(target);
kind_found = Specifications__evaluates_to(new_value);
invocation_list *new_invl = Specifications__invocation_list(new_value);
if (new_invl) {
INVOCATION_VARIABLE(new_inv);
LOOP_THROUGH_INVOCATION_LIST(new_inv, new_invl)
if (Code__Invocations__test_flag(new_inv, PASSED_INVFLAG)) break;
if (new_inv) kind_found = new_inv->kind_resulting;
}
LOGIF(MATCHING, "Kinds found: $u, wanted: $u\n", kind_found, kind_wanted);
if (((Kinds__eq(kind_wanted, K_understanding)) &&
(Kinds__eq(kind_found, K_understanding) == FALSE))
|| (Kinds__compatible(kind_found, kind_wanted) == NEVER_MATCH)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, target->word_ref1, target->word_ref2);
Problems__quote_kind(3, Specifications__evaluates_to(target));
Problems__quote_words(4, new_value->word_ref1, new_value->word_ref2);
Problems__quote_kind(5, Specifications__evaluates_to(new_value));
Problems__handmade_problem(_P_(C16ChangeToWrongValue));
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 2598 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 2194 "inform7/Chapter 16/Type Checking.w"
;
/* if this evaluates something, is it a value of the right kind? */
if (invocation_passed)
{
#line 2772 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.5)");
if (Specifications__species_is(found, PHRASE_TO_DECIDE_VALUE_SPC)) {
kind *kind_needed = Specifications__get_kind(expected);
int outcome_test = ALWAYS_MATCH;
if (kind_needed) {
LOGIF(MATCHING, "(P%d) Checking returned $u against desired $u\n",
ref, inv->kind_resulting, kind_needed);
outcome_test = Kinds__compatible(inv->kind_resulting, kind_needed);
}
switch (outcome_test) {
case NEVER_MATCH: invocation_passed = FALSE; break;
case SOMETIMES_MATCH: best_result = SOMETIMES_MATCH; break;
}
}
}
#line 2197 "inform7/Chapter 16/Type Checking.w"
;
/* are there any special rules about invoking this phrase? */
if (invocation_passed)
{
#line 2791 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.6)");
if ((invocation_passed) && (inv->phrase_options_invoked)) {
int cso = Code__Phrases__Options__parse_invoked_options(
inv, (problem_threshold >= 2)?TRUE:FALSE);
if (cso == FALSE) invocation_passed = FALSE;
}
}
#line 2200 "inform7/Chapter 16/Type Checking.w"
;
if (invocation_passed)
{
#line 2814 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(i.2.7)");
if ((Code__Phrases__TypeData__is_a_say_phrase(ph)) &&
(Code__Invocations__get_number_tokens(inv) == 1) &&
(Specifications__Storage__get_storage_form(Code__Invocations__get_token_as_parsed(inv, 0)) == PROPERTY_VALUE_SPC)) {
Specifications__set_flag(Code__Invocations__get_token_as_parsed(inv, 0), RECORD_AS_SELF_SPFLAG);
Code__Invocations__set_flag(inv, SAVE_SELF_INVFLAG);
}
}
#line 2201 "inform7/Chapter 16/Type Checking.w"
;
if (invocation_passed)
{
#line 2830 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(1.2.8)");
if (ph) {
char *required = Code__Phrases__TypeData__only_in(ph);
if (required) {
if (strcmp(required, "loop") == 0) {
LOGIF(MATCHING, "Required to be inside loop body\n");
if (Code__Frames__Blocks__inside_a_loop_body() == FALSE) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C16CantUseOutsideLoop));
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 = Code__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__handmade_problem(_P_(C16CantUseOutsideStructure));
Problems__issue_problem_segment(
"%1 makes sense only inside a '%2' block.");
Problems__issue_problem_end();
}
}
}
}
}
}
#line 2202 "inform7/Chapter 16/Type Checking.w"
;
if ((invocation_passed) && (no_deprecated_features))
{
#line 2866 "inform7/Chapter 16/Type Checking.w"
LOG_STAGE("(1.2.9)");
if ((ph) && (ph->type_data.now_deprecated)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__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 2204 "inform7/Chapter 16/Type Checking.w"
;
}
}
#line 2155 "inform7/Chapter 16/Type Checking.w"
;
Code__Invocations__set_flag(inv, TESTED_INVFLAG);
if (invocation_passed) {
Code__Invocations__set_flag(inv, PASSED_INVFLAG);
if (with_qualifications) Code__Invocations__set_flag(inv, UNPROVEN_INVFLAG);
} else if (no_gross_problems_thrown > no_gross_problems_thrown_before)
Code__Invocations__set_flag(inv, GROSSLY_FAILED_INVFLAG);
}
#line 3206 "inform7/Chapter 16/Type Checking.w"
;
}
#line 3157 "inform7/Chapter 16/Type Checking.w"
else if (most_likely_to_have_been_intended)
{
#line 3211 "inform7/Chapter 16/Type Checking.w"
int ec = problem_count;
ph = most_likely_to_have_been_intended->phrase_invoked;
int i;
for (i=0; i<Code__Invocations__get_number_tokens(most_likely_to_have_been_intended); i++) {
typecheck_recursive(Code__Invocations__get_token_as_parsed(most_likely_to_have_been_intended, i),
ph->type_data.token_sequence[i].to_match, 0, depth+1, NULL);
if (problem_count > ec) break;
}
if (problem_count == ec) {
kind *K = most_likely_to_have_been_intended->kind_resulting;
kind *W = Specifications__get_kind(expected);
if ((K) && (W) && (Kinds__compatible(K, W) == NEVER_MATCH)) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, found->word_ref1, found->word_ref2);
Problems__quote_kind(3, K);
Problems__quote_kind(4, W);
Problems__handmade_problem(_P_(C16BadIntermediateKind));
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;
}
Problems__sentence_problem(_P_(BelievedImpossible),
"the ingredients in this phrase do not fit it",
"but I am confused enough by this that I can't give a very helpful "
"problem message. Sorry about that.");
}
}
#line 3159 "inform7/Chapter 16/Type Checking.w"
else {
if (say_w1 >= 0) parse_nt_against_word_range(failed_text_substitution_diagnosis_NTM, say_w1, say_w2, NULL, NULL);
else
{
#line 3307 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16AllInvsFailed));
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 3162 "inform7/Chapter 16/Type Checking.w"
;
}
return NEVER_MATCH;
}
#line 2015 "inform7/Chapter 16/Type Checking.w"
;
}
#line 486 "inform7/Chapter 16/Type Checking.w"
;
return best_result;
}
#line 398 "inform7/Chapter 16/Type Checking.w"
;
}
#line 629 "inform7/Chapter 16/Type Checking.w"
int structural_phrase_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 641 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_problem(_P_(C16WrongOtherwise),
"inside an 'if ... begin'/'end if' an 'otherwise' (or 'else') "
"must be a single word phrase",
"so it appears that the two ways to use 'otherwise' have been "
"mixed up. It can either be used as 'if ... begin; ...; "
"otherwise; ...; end if', or as 'if ..., ...; otherwise ...;'.");
}
#line 630 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 651 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_problem_with_note(_P_(C16WrongOtherwise2),
"an 'otherwise if' (or 'else if') which uses a comma to give "
"a single consequence can only be used immediately following "
"an equally simple 'if'",
"and can't be used in the middle of a begin ... end if block.",
"To provide alternatives within such a block, use 'otherwise "
"if ... condition...;' (in the same way that one would use "
"'otherwise;' without a condition).");
}
#line 631 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 663 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_problem(_P_(C16WrongOtherwise3),
"an 'otherwise if' (or 'else if') should not take a 'begin'",
"but acts as a divider within a begin/end block all by itself.");
}
#line 632 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 670 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_problem_with_note(_P_(C16WrongThen),
"'then' should be followed by a phrase",
"and should not be the end of the 'if'.",
"There are two forms of 'if': either 'if ... then ...' (where a "
"comma can be used in place of 'then'), or the more complex 'if "
"... begin; ...; end if'. Perhaps you meant to write 'begin' "
"instead of 'then'?");
}
#line 633 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 681 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_problem_with_note(_P_(C16PossibleUnterminatedIf),
"this is a phrase which I don't recognise",
"even though it starts with 'if'. 'If' phrases normally have one "
"of two forms: 'if (condition), (do something)' and 'if (condition) "
"begin; ... ; end if'.",
"The difference is that the begin/end version can encompass "
"multiple-phrase consequences if the condition is true, whereas "
"the simpler form allows only one phrase to count as the 'do "
"something' part.");
}
#line 634 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 694 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_problem_with_note(_P_(C16PossibleUnterminatedUnless),
"this is a phrase which I don't recognise",
"even though it starts with 'unless'. 'Unless' phrases normally have "
"one of two forms: 'unless (condition), (do something)' and 'unless "
"(condition) begin; ... ; end unless'.",
"The difference is that the begin/end version can encompass "
"multiple-phrase consequences if the condition is true, whereas "
"the simpler form allows only one phrase to count as the 'do "
"something' part.");
}
#line 635 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 707 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_problem(_P_(C16WrongContinue),
"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 636 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 637 "inform7/Chapter 16/Type Checking.w"
#line 741 "inform7/Chapter 16/Type Checking.w"
int unknown_text_shape_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 745 "inform7/Chapter 16/Type Checking.w"
int unknown_text_substitution_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 755 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16SayComma));
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 747 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 766 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16SayUnicode));
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 748 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 784 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16SayUnknownCondition));
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 749 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 809 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16SayUnknown));
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 750 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 751 "inform7/Chapter 16/Type Checking.w"
#line 869 "inform7/Chapter 16/Type Checking.w"
int unknown_value_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 887 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16NumberOfTurns));
{
#line 973 "inform7/Chapter 16/Type Checking.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 888 "inform7/Chapter 16/Type Checking.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 870 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 897 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16OutOfPlay));
{
#line 973 "inform7/Chapter 16/Type Checking.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 898 "inform7/Chapter 16/Type Checking.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 871 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 935 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16MidTextUnicode));
{
#line 973 "inform7/Chapter 16/Type Checking.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 936 "inform7/Chapter 16/Type Checking.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 872 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 951 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16UnknownCondition));
{
#line 973 "inform7/Chapter 16/Type Checking.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 952 "inform7/Chapter 16/Type Checking.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 873 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 966 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16Unknown));
{
#line 973 "inform7/Chapter 16/Type Checking.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 967 "inform7/Chapter 16/Type Checking.w"
;
Problems__issue_problem_end();
}
#line 874 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 875 "inform7/Chapter 16/Type Checking.w"
int unknown_use_option_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 911 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16OptionlessOption));
{
#line 973 "inform7/Chapter 16/Type Checking.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 912 "inform7/Chapter 16/Type Checking.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 877 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 966 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16Unknown));
{
#line 973 "inform7/Chapter 16/Type Checking.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 967 "inform7/Chapter 16/Type Checking.w"
;
Problems__issue_problem_end();
}
#line 878 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 879 "inform7/Chapter 16/Type Checking.w"
int unknown_activity_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 924 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16ActivityOf));
{
#line 973 "inform7/Chapter 16/Type Checking.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 925 "inform7/Chapter 16/Type Checking.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 881 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 966 "inform7/Chapter 16/Type Checking.w"
Problems__handmade_problem(_P_(C16Unknown));
{
#line 973 "inform7/Chapter 16/Type Checking.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 967 "inform7/Chapter 16/Type Checking.w"
;
Problems__issue_problem_end();
}
#line 882 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 883 "inform7/Chapter 16/Type Checking.w"
#line 3245 "inform7/Chapter 16/Type Checking.w"
int failed_text_substitution_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 3256 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_in_detail_problem(_P_(C16Time2), w1, w2,
"this asked to say 'time' itself",
"rather than any specific time. (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();
}
#line 3246 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 3256 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_in_detail_problem(_P_(C16Time2), w1, w2,
"this asked to say 'time' itself",
"rather than any specific time. (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();
}
#line 3247 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 3267 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_in_detail_problem(_P_(C16SayDescription), w1, w2,
"this asked to say something which describes items too vaguely",
"and so does not (or not in an elementary enough way) tell "
"me exactly which thing or room should have its name printed.");
}
#line 3248 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 3275 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_in_detail_problem(_P_(C16SayAList), w1, w2,
"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 3249 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 3285 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_in_detail_problem(_P_(C16AllSayInvsFailed), w1, w2,
"this asked to say something of a kind which can't be said",
"or rather, printed. Although this problem can arise when you "
"use complicated text substitutions which come in variant "
"forms depending on the kinds of value used, far more often "
"what this means is just that you tried to use a substituted "
"value (e.g., in 'say \"The dial reads [V].\"') of a kind "
"which could not be printed out. For instance, if V is a "
"number or a piece of text, there is no problem: but if V "
"is a parsing topic, say an entry in a 'topic' column of "
"a table, then this problem will arise.");
}
#line 3250 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 3300 "inform7/Chapter 16/Type Checking.w"
Problems__sentence_in_detail_problem(_P_(BelievedImpossible), w1, w2,
"this asked to say something which I do not recognise",
"either as a value or as one of the possible text substitutions.");
}
#line 3251 "inform7/Chapter 16/Type Checking.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 3252 "inform7/Chapter 16/Type Checking.w"
#line 3322 "inform7/Chapter 16/Type Checking.w"
void Specifications__Matching__note_inv_token_text(specification *found) {
if ((Specifications__Values__is_actual_CONSTANT_of_kind(found, K_number)) ||
(Specifications__Values__is_actual_CONSTANT_of_kind(found, K_text))) return;
inv_token_problem_token *itpt;
LOOP_OVER(itpt, inv_token_problem_token)
if ((itpt->word_ref1 == found->word_ref1) && (itpt->word_ref2 == found->word_ref2))
return;
itpt = CREATE(inv_token_problem_token);
itpt->word_ref1 = found->word_ref1; itpt->word_ref2 = found->word_ref2;
itpt->as_parsed = found; itpt->already_described = FALSE;
}
#line 3339 "inform7/Chapter 16/Type Checking.w"
kind *fix_arithmetic_operand(specification *operand, int depth) {
if (Specifications__is_UNKNOWN(operand)) return NULL;
specification *expected = operand;
if (Specifications__Values__is_CONSTANT_construction(operand, CON_property)) {
property *prn = Specifications__Values__get_property_name_if_any(operand);
if (Properties__is_either_or(prn) == FALSE)
expected = Specifications__Values__new_generic_CONSTANT(Properties__Valued__kind(prn));
}
if (typecheck_recursive(operand, expected, 2, depth+1, NULL) != ALWAYS_MATCH)
return NULL;
kind *K = Specifications__evaluates_to(operand);
return K;
}
#line 3359 "inform7/Chapter 16/Type Checking.w"
int condition_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 3362 "inform7/Chapter 16/Type Checking.w"
int condition_problem_part_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 3366 "inform7/Chapter 16/Type Checking.w"
int condition_problem_part_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0;
{
#line 3377 "inform7/Chapter 16/Type Checking.w"
if (preform_lookahead_mode == FALSE) {
Problems__quote_words(4, w1, w2);
Problems__issue_problem_segment("'%4' was okay; ");
}
}
#line 3368 "inform7/Chapter 16/Type Checking.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = INVALID_CP_BIT;
{
#line 3385 "inform7/Chapter 16/Type Checking.w"
if (preform_lookahead_mode == FALSE) {
Problems__quote_words(4, w1, w2);
Problems__issue_problem_segment(
"'%4' only made sense as a value, which can't be used as a condition; ");
}
}
#line 3369 "inform7/Chapter 16/Type Checking.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 3394 "inform7/Chapter 16/Type Checking.w"
if (preform_lookahead_mode == FALSE) {
Problems__quote_words(4, w1, w2);
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 3370 "inform7/Chapter 16/Type Checking.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 3405 "inform7/Chapter 16/Type Checking.w"
if (preform_lookahead_mode == FALSE) {
Problems__quote_words(4, w1, w2);
Problems__issue_problem_segment("'%4' did not make sense; ");
}
}
#line 3371 "inform7/Chapter 16/Type Checking.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = INVALID_CP_BIT;
{
#line 3405 "inform7/Chapter 16/Type Checking.w"
if (preform_lookahead_mode == FALSE) {
Problems__quote_words(4, w1, w2);
Problems__issue_problem_segment("'%4' did not make sense; ");
}
}
#line 3372 "inform7/Chapter 16/Type Checking.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 3373 "inform7/Chapter 16/Type Checking.w"
#line 210 "inform7/Chapter 16/Invocations.w"
invocation *Code__Invocations__new(void) {
invocation *inv = CREATE(invocation);
inv->inv_packed_record = 0;
Code__Invocations__set_phrase_invoked(inv, NULL);
inv->say_verb = NULL;
inv->modal_verb = NULL;
inv->say_verb_negated = FALSE;
inv->say_adjective = NULL;
inv->kind_resulting = NULL;
inv->phrase_options_invoked = NULL;
inv->ssp_segment_count = 0;
inv->ssp_closing_segment_wn = -1;
inv->invocation_w1 = -1; inv->invocation_w2 = -1;
inv->tokens_invoked = NULL;
inv->kind_variable_declarations = NULL;
return inv;
}
#line 231 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__log(invocation *inv) {
int i;
if (inv == NULL) { LOG("<null invocation>"); return; }
char *verdict = "untested";
if (Code__Invocations__test_flag(inv, TESTED_INVFLAG)) verdict = "failed ";
if (Code__Invocations__test_flag(inv, PASSED_INVFLAG)) verdict = "proven ";
if (Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG)) verdict = "unproven";
if (Code__Invocations__test_flag(inv, GROSSLY_FAILED_INVFLAG)) verdict = "gross ";
LOG("group:%d %c%c [%04d] %s ", Code__Invocations__get_group(inv),
(Code__Invocations__test_flag(inv, INSTEAD_INVFLAG))?'I':' ',
(Code__Invocations__test_flag(inv, SAVE_SELF_INVFLAG))?'s':' ',
Code__Routines__ToPhrases__sequence_count(inv->phrase_invoked),
verdict);
if (inv->say_verb) {
LOG("verb:%d", inv->say_verb->allocation_id);
if (inv->modal_verb) LOG("modal:%d", inv->modal_verb->allocation_id);
} else if (inv->say_adjective) {
LOG("adj:%d", inv->say_adjective->allocation_id);
} else {
Code__Phrases__log_briefly(inv->phrase_invoked);
for (i=0; i<Code__Invocations__get_number_tokens(inv); i++) {
LOG(" ($S", Code__Invocations__get_token_as_parsed(inv, i));
if (Code__Invocations__get_token_check_to_do(inv, i)) LOG(" =? $S", Code__Invocations__get_token_check_to_do(inv, i));
LOG(")");
}
int ow1, ow2;
Code__Invocations__get_phrase_options(inv, &ow1, &ow2);
if (ow1 >= 0) LOG(" [0x%x $W]", Code__Invocations__get_phrase_options_bitmap(inv), ow1, ow2);
kind_variable_declaration *kvd = inv->kind_variable_declarations;
for (; kvd; kvd=kvd->next) LOG(" %c=$u", 'A'+kvd->kv_number-1, kvd->kv_value);
}
}
#line 268 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_flag(invocation *inv, int flag) {
if (inv == NULL) internal_error("tried to set flag for null inv");
inv->inv_packed_record = (inv->inv_packed_record) | flag;
}
void Code__Invocations__clear_flag(invocation *inv, int flag) {
if (inv == NULL) internal_error("tried to clear flag for null inv");
inv->inv_packed_record = (inv->inv_packed_record) & (~flag);
}
int Code__Invocations__test_flag(invocation *inv, int flag) {
int f = (inv)?(inv->inv_packed_record):0;
if (f & flag) return TRUE;
return FALSE;
}
#line 287 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__get_group(invocation *inv) {
if (inv == NULL) internal_error("tried to read group of null inv");
return ((inv->inv_packed_record) & GROUP_MASK)/BASE_OF_GROUP;
}
void Code__Invocations__set_group(invocation *inv, int g) {
if (inv == NULL) internal_error("tried to set group of null inv");
if ((g<0) || (g>4095)) internal_error("tried to set group out of range");
inv->inv_packed_record = ((inv->inv_packed_record) & (~GROUP_MASK))
+ BASE_OF_GROUP*g;
}
#line 302 "inform7/Chapter 16/Invocations.w"
int inv_get_unsorted_position(invocation *inv) {
if (inv == NULL) internal_error("tried to read USN of null inv");
return ((inv->inv_packed_record) & USN_MASK)/BASE_OF_USN;
}
void inv_set_unsorted_position(invocation *inv, int n) {
if (inv == NULL) internal_error("tried to set USN of null inv");
if ((n<0) || (n>2047)) internal_error("tried to set USN out of range");
inv->inv_packed_record = ((inv->inv_packed_record) & (~USN_MASK))
+ BASE_OF_USN*n;
}
#line 317 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_word_range(invocation *inv, int w1, int w2) {
if (inv == NULL) internal_error("tried to set word range of null inv");
inv->invocation_w1 = w1; inv->invocation_w2 = w2;
}
#line 325 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_verb_conjugation(invocation *inv,
verb_conjugation *vc, verb_conjugation *modal, int neg) {
if (inv == NULL) internal_error("tried to set VC of null inv");
inv->say_verb = vc;
inv->modal_verb = modal;
inv->say_verb_negated = neg;
}
#line 336 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_adjectival_phrase(invocation *inv, adjectival_phrase *aph) {
if (inv == NULL) internal_error("tried to set ADJ of null inv");
inv->say_adjective = aph;
}
#line 345 "inform7/Chapter 16/Invocations.w"
invocation_token_list *itl_new(void) {
invocation_token_list *itl = CREATE(invocation_token_list);
itl->token_as_parsed = NULL;
itl->token_check_to_do = NULL;
itl->token_to_be_parsed_against = NULL;
itl->next = NULL;
return itl;
}
#line 358 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_token_check_to_do(invocation *inv, int i, specification *spec) {
int k;
invocation_token_list *itl;
if (i<0) internal_error("tried to set token out of range");
if (inv->tokens_invoked == NULL) inv->tokens_invoked = itl_new();
for (itl = inv->tokens_invoked, k = 0; itl; itl = itl->next, k++) {
if (k == i) { itl->token_check_to_do = spec; return; }
if (itl->next == NULL) itl->next = itl_new();
}
}
void Code__Invocations__set_token_as_parsed(invocation *inv, int i, specification *spec) {
int k;
invocation_token_list *itl;
if (i<0) internal_error("tried to set token out of range");
if (inv->tokens_invoked == NULL) inv->tokens_invoked = itl_new();
for (itl = inv->tokens_invoked, k = 0; itl; itl = itl->next, k++) {
if (k == i) { itl->token_as_parsed = spec; return; }
if (itl->next == NULL) itl->next = itl_new();
}
}
void Code__Invocations__set_token_to_be_parsed_against(invocation *inv, int i, specification *spec) {
int k;
invocation_token_list *itl;
if (i<0) internal_error("tried to set token out of range");
if (inv->tokens_invoked == NULL) inv->tokens_invoked = itl_new();
for (itl = inv->tokens_invoked, k = 0; itl; itl = itl->next, k++) {
if (k == i) { itl->token_to_be_parsed_against = spec; return; }
if (itl->next == NULL) itl->next = itl_new();
}
}
#line 394 "inform7/Chapter 16/Invocations.w"
specification *Code__Invocations__get_token_check_to_do(invocation *inv, int i) {
int k;
invocation_token_list *itl;
for (itl = inv->tokens_invoked, k = 0; itl; itl = itl->next, k++)
if (k == i) return itl->token_check_to_do;
return NULL;
}
specification *Code__Invocations__get_token_as_parsed(invocation *inv, int i) {
int k;
invocation_token_list *itl;
for (itl = inv->tokens_invoked, k = 0; itl; itl = itl->next, k++)
if (k == i) return itl->token_as_parsed;
return NULL;
}
specification *Code__Invocations__get_token_to_be_parsed_against(invocation *inv, int i) {
int k;
invocation_token_list *itl;
for (itl = inv->tokens_invoked, k = 0; itl; itl = itl->next, k++)
if (k == i) return itl->token_to_be_parsed_against;
return NULL;
}
kind *Code__Invocations__get_token_variable_kind(invocation *inv, int i) {
int k;
invocation_token_list *itl;
for (itl = inv->tokens_invoked, k = 0; itl; itl = itl->next, k++)
if (k == i) return itl->kind_of_new_variable;
return NULL;
}
void Code__Invocations__set_token_variable_kind(invocation *inv, int i, kind *K) {
int k;
invocation_token_list *itl;
for (itl = inv->tokens_invoked, k = 0; itl; itl = itl->next, k++)
if (k == i)
itl->kind_of_new_variable = K;
}
int Code__Invocations__get_no_tokens(invocation *inv) {
int k;
invocation_token_list *itl;
for (itl = inv->tokens_invoked, k = 0; itl; itl = itl->next, k++) ;
return k;
}
#line 444 "inform7/Chapter 16/Invocations.w"
phrase *Code__Invocations__get_phrase_invoked(invocation *inv) {
if (inv == NULL) return NULL;
return inv->phrase_invoked;
}
void Code__Invocations__set_phrase_invoked(invocation *inv, phrase *ph) {
inv->phrase_invoked = ph;
}
void Code__Invocations__set_instead_flag(invocation *inv, int t) {
if (t) Code__Invocations__set_flag(inv, INSTEAD_INVFLAG);
else Code__Invocations__clear_flag(inv, INSTEAD_INVFLAG);
}
#line 462 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__get_number_tokens(invocation *inv) {
if (inv == NULL) internal_error("tried to read NTI of null inv");
if (inv->phrase_invoked) return Code__Phrases__TypeData__get_no_tokens(&(inv->phrase_invoked->type_data));
return 0;
}
#line 471 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__set_phrase_options(invocation *inv, int w1, int w2) {
if (inv->phrase_options_invoked == NULL) {
inv->phrase_options_invoked = CREATE(invocation_options);
inv->phrase_options_invoked->options = 0;
}
inv->phrase_options_invoked->options_invoked_w1 = w1;
inv->phrase_options_invoked->options_invoked_w2 = w2;
}
#line 483 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__get_phrase_options(invocation *inv, int *w1, int *w2) {
if (inv->phrase_options_invoked == NULL) { *w1 = -1; *w2 = -1; }
else {
*w1 = inv->phrase_options_invoked->options_invoked_w1;
*w2 = inv->phrase_options_invoked->options_invoked_w2;
}
}
#line 495 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__get_phrase_options_bitmap(invocation *inv) {
if (inv->phrase_options_invoked == NULL) return 0;
return inv->phrase_options_invoked->options;
}
void Code__Invocations__set_phrase_options_bitmap(invocation *inv, int further_bits) {
if (further_bits == 0) return;
if (inv->phrase_options_invoked == NULL) {
inv->phrase_options_invoked = CREATE(invocation_options);
inv->phrase_options_invoked->options_invoked_w1 = -1;
inv->phrase_options_invoked->options_invoked_w2 = -1;
inv->phrase_options_invoked->options = 0;
}
inv->phrase_options_invoked->options |= further_bits;
}
#line 515 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__implies_newline(invocation *inv) {
if (!(Code__Phrases__TypeData__is_a_say_phrase(inv->phrase_invoked))) return FALSE;
if (!(TEST_COMPILATION_MODE(IMPLY_NEWLINES_IN_SAY_CMODE))) return FALSE;
if (Code__Invocations__test_flag(inv, SUPPRESS_IMPLIED_NEWLINES_INVFLAG)) return FALSE;
return TRUE;
}
#line 527 "inform7/Chapter 16/Invocations.w"
invocation_list *Code__Invocations__Lists__new(void) {
invocation_list *invl = CREATE(invocation_list);
invl->list_head = NULL; invl->list_tail = NULL;
return invl;
}
#line 536 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__Lists__append(invocation_list *to, invocation_list *from) {
invocation_list_entry *ent;
for (ent=from->list_head; ent; ent=ent->next)
Code__Invocations__Lists__add(to, ent->listed_inv);
}
#line 545 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__Lists__add(invocation_list *invl, invocation *inv) {
invocation_list_entry *ent = CREATE(invocation_list_entry);
ent->listed_inv = inv; ent->next = NULL;
if (invl->list_head) invl->list_tail->next = ent;
else invl->list_head = ent;
invl->list_tail = ent;
}
#line 556 "inform7/Chapter 16/Invocations.w"
int Code__Invocations__Lists__length(invocation_list *invl) {
if (invl == NULL) return 0;
int L = 0;
invocation_list_entry *inve;
for (inve = invl->list_head; inve; inve = inve->next) L++;
return L;
}
invocation *first_in_invocation_list(invocation_list *invl) {
if ((invl == NULL) || (invl->list_head == NULL)) return NULL;
return invl->list_head->listed_inv;
}
#line 576 "inform7/Chapter 16/Invocations.w"
invocation **pigeon_holes = NULL;
int number_of_pigeon_holes = 0;
void Code__Invocations__Lists__sort(invocation_list *invl) {
int L = Code__Invocations__Lists__length(invl);
{
#line 601 "inform7/Chapter 16/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 *), INV_LIST_MREASON);
}
}
#line 581 "inform7/Chapter 16/Invocations.w"
;
int i;
invocation_list_entry *ent;
for (i=0, ent=invl->list_head; (i<L) && (ent); i++, ent=ent->next) {
pigeon_holes[i] = ent->listed_inv;
inv_set_unsorted_position(pigeon_holes[i], (i>2047)?2047:i);
}
qsort(pigeon_holes, (size_t) L, sizeof(invocation *), inv_comparison);
for (i=0, ent=invl->list_head; i<L; i++, ent=ent->next)
ent->listed_inv = pigeon_holes[i];
}
#line 635 "inform7/Chapter 16/Invocations.w"
int inv_comparison(const void *i1, const void *i2) {
invocation **inv1s = (invocation **) i1; invocation *inv1 = *inv1s;
invocation **inv2s = (invocation **) i2; invocation *inv2 = *inv2s;
/* (a) sort by group */
int delta = Code__Invocations__get_group(inv1) - Code__Invocations__get_group(inv2);
if (delta != 0) return delta;
/* (b) sort by logical priority */
delta = Code__Routines__ToPhrases__sequence_count(inv1->phrase_invoked) - Code__Routines__ToPhrases__sequence_count(inv2->phrase_invoked);
if (delta != 0) return delta;
/* (c) sort by creation sequence */
return inv_get_unsorted_position(inv1) - inv_get_unsorted_position(inv2);
}
#line 692 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__Lists__log(invocation_list *invl) {
INVOCATION_VARIABLE(inv);
LOG("Invocation list (%d):\n", Code__Invocations__Lists__length(invl));
LOOP_THROUGH_INVOCATION_LIST(inv, invl)
LOG("P%d: $e\n", inv_pos, inv);
}
#line 703 "inform7/Chapter 16/Invocations.w"
void Code__Invocations__Lists__log_in_detail(invocation_list *invl) {
INVOCATION_VARIABLE(inv);
LOG("Invocation list in detail (%d):\n", Code__Invocations__Lists__length(invl));
LOOP_THROUGH_INVOCATION_LIST(inv, invl) {
int j;
LOG("P%d: $e\n", inv_pos, inv);
for (j=0; j<Code__Invocations__get_number_tokens(inv); j++) {
specification *tok = Code__Invocations__get_token_as_parsed(inv, j);
LOG(" %d: $S\n", j, tok);
if (Specifications__has_invocation_list(tok)) {
LOG_INDENT;
Code__Invocations__Lists__log_in_detail(Specifications__invocation_list(tok));
LOG_OUTDENT;
}
}
}
}
#line 96 "inform7/Chapter 17/Properties.w"
property *Properties__obtain(int w1, int w2, int valued) {
meaning_list *ml = Parser__SP__parse_excerpt(PROPERTY_MC, w1, w2);
property *prn;
if (ml == NULL) {
prn = Properties__create(w1, w2);
if (valued) {
Properties__Valued__make_setting_relation(prn, w1, w2);
prn->either_or = FALSE;
} else {
prn->either_or = TRUE;
}
} else {
prn = RETRIEVE_POINTER_property(
Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
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 121 "inform7/Chapter 17/Properties.w"
property *Properties__create(int w1, int w2) {
Text__Languages__remove_article(&w1, &w2);
{
#line 144 "inform7/Chapter 17/Properties.w"
int unfortunate = FALSE;
if ((parse_nt_against_word_range(k_kind_NTM, w1, w2, NULL, NULL)) && (most_recent_result_p == K_value)) {
unfortunate = TRUE;
Problems__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 (parse_nt_against_word_range(unsuitable_name_NTM, w1, w2, NULL, NULL)) {
unfortunate = TRUE;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C17PropertyNameUnsuitable));
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) {
w1 = lexer_wordcount;
Text__feed_into_lexer("problem recovery name", FALSE, NULL);
w2 = lexer_wordcount-1;
}
}
#line 123 "inform7/Chapter 17/Properties.w"
;
{
#line 178 "inform7/Chapter 17/Properties.w"
if (parse_nt_against_word_range(spec_type_expression_or_value_NTM, w1, w2, NULL, NULL)) {
int okay = FALSE;
specification *spec = most_recent_result_p;
if (Specifications__Values__is_generic_CONSTANT(spec)) okay = TRUE;
if (Specifications__Values__is_actual_CONSTANT_construction(spec, CON_table_column)) okay = TRUE;
if (Specifications__Values__is_actual_CONSTANT_construction(spec, CON_property)) okay = TRUE;
if (Specifications__species_is(spec, DESCRIPTION_SPC)) okay = TRUE;
if (Specifications__species_is(spec, NONLOCAL_VARIABLE_SPC)) okay = TRUE;
if (okay == FALSE) {
LOG("Existing meaning: $S", spec);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_kind_of(3, spec);
Problems__handmade_problem(_P_(C17PropertyNameClash));
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 124 "inform7/Chapter 17/Properties.w"
;
property *prn = CREATE(property);
{
#line 204 "inform7/Chapter 17/Properties.w"
prn->word_ref1 = w1; prn->word_ref2 = w2;
prn->ambiguous_name = parse_nt_against_word_range(name_looking_like_property_test_NTM, w1, w2, 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 127 "inform7/Chapter 17/Properties.w"
;
{
#line 221 "inform7/Chapter 17/Properties.w"
if (parse_nt_against_word_range(k_kind_NTM, w1, w2, NULL, NULL))
Properties__Valued__make_coincide_with_kind(prn, most_recent_result_p);
}
#line 128 "inform7/Chapter 17/Properties.w"
;
Formats__Inform6__compose_identifier(prn->original_name, 'p', prn->allocation_id, w1, w2);
strcpy(prn->translated_name, prn->original_name);
{
#line 239 "inform7/Chapter 17/Properties.w"
if (parse_nt_against_word_range(notable_properties_NTM, w1, w2, 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;
}
}
Config__Plugins__Call__new_property_notify(prn);
}
#line 132 "inform7/Chapter 17/Properties.w"
;
if (w1 >= 0)
{
#line 277 "inform7/Chapter 17/Properties.w"
Semantics__Nouns__ExcerptMeanings__register(
PROPERTY_MC, 0, w1, w2, STORE_POINTER_property(prn));
Semantics__Nouns__ExcerptMeanings__register_assemblage(
PROPERTY_MC, 0,
Text__Languages__merge(property_name_construction_NTM, 0,
Text__Words__from_range(w1, w2)),
STORE_POINTER_property(prn));
}
#line 134 "inform7/Chapter 17/Properties.w"
else Properties__exclude_from_index(prn);
LOGIF(PROPERTY_CREATIONS, "Created property: $Y = %s\n", prn, prn->translated_name);
return prn;
}
#line 230 "inform7/Chapter 17/Properties.w"
int notable_properties_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 235 "inform7/Chapter 17/Properties.w"
#line 271 "inform7/Chapter 17/Properties.w"
int property_name_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 273 "inform7/Chapter 17/Properties.w"
#line 288 "inform7/Chapter 17/Properties.w"
specification *Properties__to_specification(property *prn) {
if (prn == NULL) internal_error("converted null property to value");
kind *stored = prn->property_value_kind;
if (prn->either_or) stored = K_truth_state;
kind *K = Kinds__unary_construction(CON_property, stored);
specification *spec = Specifications__Values__new_actual_CONSTANT(K);
Specifications__set_structure_field(spec, STORE_POINTER_property(prn));
return spec;
}
property *Properties__from_specification(specification *spec) {
if (!(Specifications__Values__is_actual_CONSTANT_construction(spec, CON_property))) {
LOG("Bad spec is: $S\n", spec);
internal_error("tried to find peop inside SP of wrong type");
}
property *prn = RETRIEVE_POINTER_property(Specifications__get_structure_field(spec));
if (prn == NULL) internal_error("found NULL prop within PROPERTY spec");
return prn;
}
#line 313 "inform7/Chapter 17/Properties.w"
int property_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 314 "inform7/Chapter 17/Properties.w"
Text__Languages__remove_the(&w1, &w2);
property *prn;
LOOP_OVER(prn, property) {
int pn1 = prn->word_ref1, pn2 = prn->word_ref2;
if ((w2-w1 == pn2-pn1) && (Text__compare_word_range(w1, w1+pn2-pn1, pn1, pn2))) {
*XP = prn;
return w1+pn2-pn1;
}
}
return FALSE;
}
#line 329 "inform7/Chapter 17/Properties.w"
int either_or_property_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 330 "inform7/Chapter 17/Properties.w"
Text__Languages__remove_the(&w1, &w2);
property *prn;
LOOP_OVER(prn, property)
if (prn->either_or) {
int pn1 = prn->word_ref1, pn2 = prn->word_ref2;
if ((w2-w1 == pn2-pn1) && (Text__compare_word_range(w1, w1+pn2-pn1, pn1, pn2))) {
*XP = prn;
return TRUE;
}
}
return FALSE;
}
int value_property_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 344 "inform7/Chapter 17/Properties.w"
Text__Languages__remove_the(&w1, &w2);
property *prn;
LOOP_OVER(prn, property)
if (prn->either_or == FALSE) {
int pn1 = prn->word_ref1, pn2 = prn->word_ref2;
if ((w2-w1 == pn2-pn1) && (Text__compare_word_range(w1, w1+pn2-pn1, pn1, pn2))) {
*XP = prn;
return TRUE;
}
}
return FALSE;
}
#line 361 "inform7/Chapter 17/Properties.w"
int property_name_v_NTMR(int w1, int w2, int *X, void **XP) {
#line 362 "inform7/Chapter 17/Properties.w"
property *prn;
LOOP_OVER(prn, property) {
int pn1 = prn->word_ref1, pn2 = prn->word_ref2;
if ((w2-w1 >= pn2-pn1) && (Text__compare_word_range(w1, w1+pn2-pn1, pn1, pn2))) {
*XP = prn;
return w1+pn2-pn1;
}
}
return FALSE;
}
#line 379 "inform7/Chapter 17/Properties.w"
int name_looking_like_property_test_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 381 "inform7/Chapter 17/Properties.w"
#line 386 "inform7/Chapter 17/Properties.w"
int ambiguous_property_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 387 "inform7/Chapter 17/Properties.w"
property *prn;
LOOP_OVER(prn, property)
if (prn->ambiguous_name) {
int pn1 = prn->word_ref1, pn2 = prn->word_ref2;
if ((w2-w1 >= pn2-pn1) && (Text__compare_word_range(w1, w1+pn2-pn1, pn1, pn2))) {
*XP = prn;
return w1+pn2-pn1;
}
}
return FALSE;
}
#line 404 "inform7/Chapter 17/Properties.w"
int Properties__match_longest(int w1, int w2) {
int maxlen = -1;
property *prn;
LOOP_OVER(prn, property) {
int x1, x2;
x1 = prn->word_ref1; x2 = prn->word_ref2;
if (x2-x1 <= w2-w1) {
int j;
for (j=0; j<=x2-x1; j++)
if (compare_words(w1+j, x1+j) == FALSE) goto NotThisOne;
if (maxlen < x2-x1) maxlen = x2-x1+1;
}
NotThisOne: ;
}
return maxlen;
}
#line 425 "inform7/Chapter 17/Properties.w"
property *fast_property_parse(int w1, int w2) {
meaning_list *ml;
ml = Parser__SP__parse_excerpt(PROPERTY_MC, w1, w2);
if (ml == NULL) return NULL;
return RETRIEVE_POINTER_property(
Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
}
#line 438 "inform7/Chapter 17/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 448 "inform7/Chapter 17/Properties.w"
void Properties__log(property *prn) {
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("=~"); log_basic_pname(neg); }
} else {
LOG("=$u", Properties__Valued__kind(prn));
}
}
void log_basic_pname(property *prn) {
if (prn == NULL) { LOG("<null-property>"); return; }
if (prn->word_ref1 >= 0) { LOG("'$W'", prn->word_ref1, prn->word_ref2); }
else { LOG("'%s'", prn->translated_name); }
}
#line 471 "inform7/Chapter 17/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 485 "inform7/Chapter 17/Properties.w"
int Properties__can_be_compiled(property *prn) {
if ((prn == NULL) || (prn->do_not_compile)) return FALSE;
return TRUE;
}
#line 494 "inform7/Chapter 17/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 504 "inform7/Chapter 17/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 514 "inform7/Chapter 17/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 531 "inform7/Chapter 17/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 557 "inform7/Chapter 17/Properties.w"
void Properties__translates(int w1, int w2, parse_node *p2) {
property *prn = NULL;
if (parse_nt_against_word_range(property_name_NTM, w1, w2, NULL, NULL)) prn = most_recent_result_p;
char *text = Text__word_text(p2->word_ref1);
{
#line 574 "inform7/Chapter 17/Properties.w"
if (prn == NULL) {
Problems__sentence_problem(_P_(C17NonPropertyTranslated),
"this property does not exist",
"so cannot be translated.");
return;
}
if ((prn->translated) && (strcmp(text, prn->translated_name) != 0)) {
Problems__sentence_problem(_P_(C17TranslatedTwice),
"this property has already been translated",
"so there must be some duplication somewhere.");
return;
}
}
#line 562 "inform7/Chapter 17/Properties.w"
;
Properties__set_translation(prn, text);
LOGIF(PROPERTY_TRANSLATIONS, "Property <$Y> translates as <%s>\n", prn, text);
if (prn->either_or)
{
#line 604 "inform7/Chapter 17/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 568 "inform7/Chapter 17/Properties.w"
;
}
#line 614 "inform7/Chapter 17/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 628 "inform7/Chapter 17/Properties.w"
int property_traverse_count = 0;
void Properties__Traverse__begin(void) {
property_traverse_count++;
}
int Properties__Traverse__visited(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 648 "inform7/Chapter 17/Properties.w"
possession_marker *Properties__get_possession_marker(property *prn) {
return &(prn->pom);
}
#line 659 "inform7/Chapter 17/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 (compile_property_value_inner(OUT, infs, prn)) return;
infs = World__Subjects__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 676 "inform7/Chapter 17/Properties.w"
int 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) {
specification *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 17/Either-Or Properties.w"
property *Properties__EitherOr__obtain(int w1, int w2, inference_subject *infs) {
if (parse_nt_against_word_range(k_kind_NTM, w1, w2, NULL, NULL)) {
Problems__sentence_problem(_P_(C17KindAdjectiveClash),
"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(w1, w2, FALSE);
prn->either_or = TRUE;
kind *K = World__Subjects__domain(infs);
if (prn->adjectival_meaning_registered == NULL)
create_adjective_from_property(prn, w1, w2, K);
else
make_new_adjective_sense_from_property(prn, w1, w2, K);
return prn;
}
#line 89 "inform7/Chapter 17/Either-Or Properties.w"
property *Properties__EitherOr__new_nameless(char *I6_form) {
property *prn = Properties__create(-1, -1);
prn->either_or = TRUE;
Properties__exclude_from_index(prn);
Properties__set_translation(prn, I6_form);
create_adjective_from_property(prn, -1, -1, K_object);
return prn;
}
#line 101 "inform7/Chapter 17/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 17/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__handmade_problem(_P_(C17BrokenNegationPair));
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 17/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 17/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 17/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_true_about(prop, owner, certainty);
}
#line 203 "inform7/Chapter 17/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 17/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 17/Either-Or Properties.w"
void create_adjective_from_property(property *prn, int w1, int w2, kind *K) {
adjective_meaning *am =
Semantics__Adjectives__Meanings__new(EORP_KADJ, STORE_POINTER_property(prn), w1, w2);
Semantics__Adjectives__Meanings__declare(am, w1, w2);
Semantics__Adjectives__Meanings__set_domain_from_kind(am, K);
prn->adjectival_phrase_registered = Semantics__Adjectives__Meanings__get_aph(am);
prn->adjectival_meaning_registered = am;
}
void make_new_adjective_sense_from_property(property *prn, int w1, int w2, kind *K) {
adjectival_phrase *aph = prn->adjectival_phrase_registered;
if (Semantics__Adjectives__Phrases__applicable_to(aph, K)) return;
adjective_meaning *am =
Semantics__Adjectives__Meanings__new(EORP_KADJ, STORE_POINTER_property(prn), w1, w2);
Semantics__Adjectives__Meanings__declare(am, w1, w2);
Semantics__Adjectives__Meanings__set_domain_from_kind(am, K);
}
#line 264 "inform7/Chapter 17/Either-Or Properties.w"
adjective_meaning *Properties__EitherOr__Adjectives__parse(parse_node *q,
int sense,
int adj_name_w1, int adj_name_w2,
int dom_name_w1, int dom_name_w2,
int cond_w1, int cond_w2,
int called_w1, int called_w2) {
return NULL;
}
#line 277 "inform7/Chapter 17/Either-Or Properties.w"
int Properties__EitherOr__Adjectives__compile(property *prn, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
#line 286 "inform7/Chapter 17/Either-Or Properties.w"
void Properties__EitherOr__Adjectives__compiling_soon(adjective_meaning *am, property *prn, int T) {
if (am == NULL) internal_error("Unregistered adjectival either/or property in either/or atom");
if (Semantics__Adjectives__Meanings__get_ready_flag(am)) return;
Semantics__Adjectives__Meanings__set_ready_flag(am);
kind *K = Semantics__Adjectives__Meanings__get_domain(am);
if (Kinds__le(K, K_object))
{
#line 306 "inform7/Chapter 17/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 = Semantics__Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Code__Schemas__modify(sch, "GetEitherOrProperty(*1, %s) == false", identifier);
sch = Semantics__Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, FALSE);
Code__Schemas__modify(sch, "SetEitherOrProperty(*1, %s, true)", identifier);
sch = Semantics__Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_FALSE_TASK, FALSE);
Code__Schemas__modify(sch, "SetEitherOrProperty(*1, %s)", identifier);
} else {
char *identifier = Properties__get_translation(prn);
i6_schema *sch = Semantics__Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Code__Schemas__modify(sch, "GetEitherOrProperty(*1, %s)", identifier);
sch = Semantics__Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, FALSE);
Code__Schemas__modify(sch, "SetEitherOrProperty(*1, %s)", identifier);
sch = Semantics__Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_FALSE_TASK, FALSE);
Code__Schemas__modify(sch, "SetEitherOrProperty(*1, %s, true)", identifier);
}
}
#line 294 "inform7/Chapter 17/Either-Or Properties.w"
else
{
#line 334 "inform7/Chapter 17/Either-Or Properties.w"
if (Properties__EitherOr__stored_in_negation(prn)) {
property *neg = Properties__EitherOr__get_negation(prn);
i6_schema *sch = Semantics__Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Code__Schemas__modify(sch, "GProperty(%k, *1, %s) == false", K,
Properties__get_translation(neg));
sch = Semantics__Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, FALSE);
Code__Schemas__modify(sch, "WriteGProperty(%k, *1, %s)", K,
Properties__get_translation(neg));
sch = Semantics__Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_FALSE_TASK, FALSE);
Code__Schemas__modify(sch, "WriteGProperty(%k, *1, %s, true)", K,
Properties__get_translation(neg));
} else {
i6_schema *sch = Semantics__Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Code__Schemas__modify(sch, "GProperty(%k, *1, %s)", K,
Properties__get_translation(prn));
sch = Semantics__Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, FALSE);
Code__Schemas__modify(sch, "WriteGProperty(%k, *1, %s, true)", K,
Properties__get_translation(prn));
sch = Semantics__Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_FALSE_TASK, FALSE);
Code__Schemas__modify(sch, "WriteGProperty(%k, *1, %s)", K,
Properties__get_translation(prn));
}
}
#line 296 "inform7/Chapter 17/Either-Or Properties.w"
;
return;
}
#line 366 "inform7/Chapter 17/Either-Or Properties.w"
int Properties__EitherOr__Adjectives__assert(property *prn,
inference_subject *infs_to_assert_on, specification *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 376 "inform7/Chapter 17/Either-Or Properties.w"
int Properties__EitherOr__Adjectives__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>");
Text__print_raw_text_to_stream(neg->word_ref1, neg->word_ref2, ifl);
INDEX("<i>");
}
return TRUE;
}
#line 13 "inform7/Chapter 17/Valued Properties.w"
property *Properties__Valued__obtain(int w1, int w2) {
return Properties__obtain(w1, w2, TRUE);
}
#line 22 "inform7/Chapter 17/Valued Properties.w"
property *Properties__Valued__obtain_within_kind(int w1, int w2, kind *K) {
property *prn = NULL;
if (K == NULL) K = K_object;
K = Kinds__weaken(K);
if (parse_nt_against_word_range(property_name_NTM, w1, w2, NULL, NULL)) {
prn = most_recent_result_p;
kind *existing_kind = prn->property_value_kind;
switch(Kinds__compatible(K, existing_kind)) {
case SOMETIMES_MATCH:
if (Kinds__compatible(existing_kind, K) != ALWAYS_MATCH)
{
#line 48 "inform7/Chapter 17/Valued Properties.w"
Problems__sentence_problem(_P_(C17BadKOVForRelationProperty),
"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 17/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 17/Valued Properties.w"
Problems__sentence_problem(_P_(C17BadKOVForRelationProperty),
"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 17/Valued Properties.w"
;
}
} else {
prn = Properties__obtain(w1, w2, TRUE);
prn->property_value_kind = K;
}
return prn;
}
#line 65 "inform7/Chapter 17/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(-1, -1);
Properties__exclude_from_index(prn);
prn->either_or = FALSE;
Properties__set_translation(prn, I6_form);
prn->property_value_kind = K;
prn->setting_bp = Properties__Valued__Relations__make_set_nameless_property_BP(prn);
prn->stored_bp = NULL;
return prn;
}
#line 80 "inform7/Chapter 17/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__Valued__Conditions__initialise(prn);
}
void Properties__Valued__make_setting_relation(property *prn, int w1, int w2) {
binary_predicate *bp = Properties__Valued__Relations__find_set_property_BP(w1, w2);
if (bp == NULL) bp = Properties__Valued__Relations__make_set_property_BP(w1, w2);
Properties__Valued__Relations__fix_property_bp(bp);
Properties__Valued__Relations__fix_property_bp(Semantics__BPs__get_reversal(bp));
prn->setting_bp = bp;
}
#line 100 "inform7/Chapter 17/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__definite(K) == FALSE) && (prn->do_not_compile == FALSE)) {
Problems__quote_words(1, prn->word_ref1, prn->word_ref2);
Problems__quote_kind(2, K);
Problems__handmade_problem(_P_(C17PropertyIndefinite));
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 17/Valued Properties.w"
void Properties__Valued__make_coincide_with_kind(property *prn, kind *K) {
Properties__Valued__set_kind(prn, K);
if (Kinds__eq(K, K_grammatical_gender)) P_grammatical_gender = prn;
prn->also_a_type = TRUE;
if (Kinds__name_can_coincide_with_property(K))
Data__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 17/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 17/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 17/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 17/Valued Properties.w"
void Properties__Valued__assert(property *prn, inference_subject *owner,
specification *val, int certainty) {
pcalc_prop *prop = Calculus__Propositions__to_set_property(prn, val);
Calculus__Propositions__assert_true_about(prop, owner, certainty);
}
#line 208 "inform7/Chapter 17/Valued Properties.w"
void Properties__Valued__compile_value(OUTPUT_STREAM, property *prn, specification *val) {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
kind *K = Properties__Valued__kind(prn);
if (K) Specifications__compile_constant_to_kind(OUT, val, K);
else Specifications__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__compile_default_value(OUT,
K, prn->word_ref1, prn->word_ref2, "property") == FALSE) {
Problems__quote_words(1, prn->word_ref1, prn->word_ref2);
Problems__handmade_problem(_P_(C17PropertyUninitialisable));
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 17/Condition Properties.w"
void Properties__Valued__Conditions__initialise(property *prn) {
prn->condition_of = NULL;
prn->condition_anonymously_named = FALSE;
}
#line 28 "inform7/Chapter 17/Condition Properties.w"
property *Properties__Valued__Conditions__new(inference_subject *infs, int n1, int n2, parse_node *set, int *already) {
int w1 = n1, w2 = n2, anon = FALSE;
*already = FALSE;
if (n1 < 0) {
kind *common_kind = NULL;
int mixed_kind = FALSE, some_new = FALSE, ck1 = -1, ck2 = -1, nk1 = -1, nk2 = -1;
parse_node *option;
for (option = set; option; option = (option->down)?(option->down->next):NULL) {
int pw1, pw2;
if (Parser__Nodes__type(option) == AND_NT) {
pw1 = option->down->word_ref1; pw2 = option->down->word_ref2;
} else {
pw1 = option->word_ref1; pw2 = option->word_ref2;
}
if (parse_nt_against_word_range(adjective_name_NTM, pw1, pw2, NULL, NULL)) {
adjectival_phrase *aph = most_recent_result_p;
instance *I = Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(aph);
kind *K = (I)?Data__Instances__kind(I):NULL;
if (common_kind == NULL) {
common_kind = K;
ck1 = pw1; ck2 = pw2;
} else {
if (Kinds__eq(K, common_kind) == FALSE) {
mixed_kind = TRUE;
nk1 = pw1; nk2 = pw2;
}
}
} else {
some_new = TRUE; nk1 = pw1; nk2 = pw2;
}
}
if (common_kind) {
property *prn = Kinds__get_coinciding_property(common_kind);
if (nk1 >= 0) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, common_kind);
Problems__quote_words(3, ck1, ck2);
Problems__quote_words(4, nk1, nk2);
Problems__handmade_problem(_P_(C17MixedExistingConstants));
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__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 17/Condition Properties.w"
int ct = 0;
property *prn;
LOOP_OVER(prn, property)
if ((prn->condition_of == infs) && (prn->condition_anonymously_named))
ct++;
w1 = lexer_wordcount;
int x1, x2;
World__Subjects__get_name_text(infs, &x1, &x2);
if (x1 >= 0) Text__splice_words(x1, x2);
else Text__feed_into_lexer(" nameless ", FALSE, NULL);
Text__feed_into_lexer(" condition ", FALSE, NULL);
if (ct > 0) {
char numb[32];
sprintf(numb, " %d ", ct+1);
Text__feed_into_lexer(numb, FALSE, NULL);
}
w2 = lexer_wordcount - 1;
}
#line 86 "inform7/Chapter 17/Condition Properties.w"
;
anon = TRUE;
}
pcalc_prop *prop = Calculus__Propositions__to_create_something(NULL, w1, w2);
prop = Calculus__Propositions__concatenate(prop,
Calculus__Propositions__to_make_a_kind(K_value));
Calculus__Propositions__assert_true(prop, prevailing_mood);
property *prn = Properties__Valued__obtain(w1, w2);
prn->either_or = FALSE;
prn->condition_of = infs;
prn->condition_anonymously_named = anon;
return prn;
}
#line 140 "inform7/Chapter 17/Condition Properties.w"
inference_subject *Properties__Valued__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 17/Indefinite Appearance.w"
void Properties__Appearance__infer(inference_subject *infs, specification *spec) {
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_indefinite_appearance_text)
{
#line 40 "inform7/Chapter 17/Indefinite Appearance.w"
Problems__infs_contradiction_problem(_P_(C17TwoAppearances),
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 17/Indefinite Appearance.w"
;
prevailing_mood = CERTAIN_CE;
if ((World__Subjects__domain(infs)) &&
(World__Subjects__is_within(infs, Kinds__as_subject(K_object))))
prevailing_mood = LIKELY_CE;
Properties__Valued__assert(P_indefinite_appearance_text, infs, spec, prevailing_mood);
}
#line 63 "inform7/Chapter 17/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) {
specification *txt = World__Inferences__get_property_value(inf);
current_sentence = World__Inferences__where_inferred(inf);
if (Config__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__inference_problem(_P_(C17IndefiniteTextMeaningless),
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 17/The Provision Relation.w"
void Properties__Valued__Relations__Provision__create_initial_stock(void) {
R_provision =
Semantics__BPs__make_pair(PROVISION_KBP,
Semantics__BPs__Terms__new(NULL), Semantics__BPs__Terms__new(NULL),
"provides", NULL, NULL, NULL, NULL,
Text__Languages__wording(relation_names_NTM, PROVISION_RELATION_NAME));
Semantics__BPs__set_index_details(R_provision, "value", "property");
}
#line 38 "inform7/Chapter 17/The Provision Relation.w"
void Properties__Valued__Relations__Provision__create_second_stock(void) {
}
#line 47 "inform7/Chapter 17/The Provision Relation.w"
int Properties__Valued__Relations__Provision__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__tcp_problem(_P_(C17BadProvides), 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 17/The Provision Relation.w"
int Properties__Valued__Relations__Provision__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
property *prn = Specifications__Values__get_property_name_if_any(spec1);
if ((infs0) && (prn)) {
World__Permissions__grant(infs0, prn, TRUE);
Data__Instances__update_adjectival_forms(prn);
return TRUE;
}
return FALSE;
}
#line 82 "inform7/Chapter 17/The Provision Relation.w"
int Properties__Valued__Relations__Provision__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 = Specifications__Values__get_property_name_if_any(asch->pt1.constant);
if ((K) && (prn)) {
if (Kinds__le(K, K_object))
{
#line 102 "inform7/Chapter 17/The Provision Relation.w"
if (Properties__is_value_property(prn))
Code__Schemas__modify(asch->schema, "WhetherProvides(*1, false, *2)");
else
Code__Schemas__modify(asch->schema, "WhetherProvides(*1, true, *2)");
}
#line 89 "inform7/Chapter 17/The Provision Relation.w"
else
{
#line 111 "inform7/Chapter 17/The Provision Relation.w"
if (World__Permissions__find(Kinds__as_subject(K), prn, TRUE))
Code__Schemas__modify(asch->schema, "true");
else
Code__Schemas__modify(asch->schema, "false");
}
#line 91 "inform7/Chapter 17/The Provision Relation.w"
;
return TRUE;
}
}
return FALSE;
}
#line 120 "inform7/Chapter 17/The Provision Relation.w"
int Properties__Valued__Relations__Provision__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 87 "inform7/Chapter 17/Measurement Adjectives.w"
binary_predicate *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 17/Measurement Adjectives.w"
measurement_definition *Properties__Measurement__retrieve(property *prn, int shape) {
measurement_definition *mdef;
LOOP_OVER(mdef, measurement_definition) {
validate_mdef(mdef);
if ((mdef_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 17/Measurement Adjectives.w"
void Properties__Measurement__validate_definitions(void) {
measurement_definition *mdef;
LOOP_OVER(mdef, measurement_definition) validate_mdef(mdef);
}
#line 142 "inform7/Chapter 17/Measurement Adjectives.w"
void validate_mdef(measurement_definition *mdef) {
if ((mdef->prop == NULL) && (mdef->pname_w1 >= 0))
{
#line 152 "inform7/Chapter 17/Measurement Adjectives.w"
if (parse_nt_against_word_range(property_name_NTM, mdef->pname_w1, mdef->pname_w2, NULL, NULL)) mdef->prop = most_recent_result_p;
else {
mdef->prop = NULL;
LOG("Validating mdef with headword $W... <$W>\n",
mdef->headword_wn, mdef->headword_wn,
mdef->pname_w1, mdef->pname_w2);
Problems__definition_problem(_P_(C17GradingUnknownProperty),
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 17/Measurement Adjectives.w"
;
if (mdef->region_threshold_evaluated == FALSE)
{
#line 170 "inform7/Chapter 17/Measurement Adjectives.w"
mdef->region_kind = NULL;
if (parse_nt_against_word_range(literal_NTM, mdef->region_threshold_w1, mdef->region_threshold_w2, NULL, NULL))
mdef->region_kind = most_recent_result_p;
if (mdef->region_kind) {
mdef->region_threshold = most_recent_result;
if ((Kinds__is_quasinumerical(mdef->region_kind) == FALSE) &&
(mdef->region_shape != MEASURE_T_EXACTLY)) {
Problems__definition_problem(_P_(C17GradingNonarithmeticKOV),
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__compatible(mdef->region_kind,
Properties__Valued__kind(mdef->prop)) != ALWAYS_MATCH) {
Problems__definition_problem(_P_(C17GradingWrongKOV),
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 %d, %d, <$W>\n",
mdef->region_threshold_w1, mdef->region_threshold_w2,
mdef->region_threshold_w1, mdef->region_threshold_w2);
Problems__definition_problem(_P_(C17GradingNonLiteral),
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 17/Measurement Adjectives.w"
;
}
#line 211 "inform7/Chapter 17/Measurement Adjectives.w"
int mdef_is_valid(measurement_definition *mdef) {
if ((mdef->prop == NULL) || (mdef->region_threshold_evaluated == FALSE)) return FALSE;
return TRUE;
}
#line 232 "inform7/Chapter 17/Measurement Adjectives.w"
int measurement_adjective_definition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 245 "inform7/Chapter 17/Measurement Adjectives.w"
Problems__definition_problem(_P_(C17GradingMisphrased),
Parser__Sentences__NPs__new_raw(w1, w2),
"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 233 "inform7/Chapter 17/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 236 "inform7/Chapter 17/Measurement Adjectives.w"
int measurement_range_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 241 "inform7/Chapter 17/Measurement Adjectives.w"
#line 255 "inform7/Chapter 17/Measurement Adjectives.w"
adjective_meaning *Properties__Measurement__Adjectives__parse(parse_node *q,
int sense,
int adj_name_w1, int adj_name_w2,
int dom_name_w1, int dom_name_w2,
int cond_w1, int cond_w2,
int called_w1, int called_w2) {
if (sense == 0) return NULL;
if (parse_nt_against_word_range(measurement_adjective_definition_NTM, cond_w1, cond_w2, NULL, NULL) == FALSE) return NULL;
int shape = most_recent_result;
int pr_w1, pr_w2, thres_w1, thres_w2;
GET_RW(measurement_adjective_definition_NTM, 1, pr_w1, pr_w2);
GET_RW(measurement_range_NTM, 1, thres_w1, thres_w2);
property *prop = most_recent_result_p;
{
#line 283 "inform7/Chapter 17/Measurement Adjectives.w"
if (adj_name_w1 != adj_name_w2) {
if (shape != MEASURE_T_EXACTLY)
Problems__definition_problem(_P_(C17MultiwordGrading),
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 (called_w1 >= 0) {
if (shape != MEASURE_T_EXACTLY)
Problems__definition_problem(_P_(C17GradingCalled),
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__definition_problem(_P_(C17GradingUnless),
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 270 "inform7/Chapter 17/Measurement Adjectives.w"
;
{
#line 334 "inform7/Chapter 17/Measurement Adjectives.w"
if (shape == MEASURE_T_EXACTLY) {
if (parse_nt_against_word_range(literal_NTM, thres_w1, thres_w2, NULL, NULL) == FALSE) return NULL;
}
}
#line 271 "inform7/Chapter 17/Measurement Adjectives.w"
;
measurement_definition *mdef = CREATE(measurement_definition);
{
#line 341 "inform7/Chapter 17/Measurement Adjectives.w"
mdef->measurement_node = q;
mdef->headword_wn = adj_name_w1;
mdef->region_threshold = 0;
mdef->region_threshold_w1 = thres_w1; mdef->region_threshold_w2 = thres_w2;
mdef->region_threshold_evaluated = FALSE;
mdef->prop = prop;
mdef->property_schema_written = FALSE;
mdef->region_shape = shape;
mdef->pname_w1 = pr_w1; mdef->pname_w2 = pr_w2;
mdef->superlative_wn = -1; /* but it may be set below */
mdef->headword_as_adjective = NULL; /* but it will certainly be set below */
}
#line 274 "inform7/Chapter 17/Measurement Adjectives.w"
;
if (shape != MEASURE_T_EXACTLY)
{
#line 359 "inform7/Chapter 17/Measurement Adjectives.w"
mdef->superlative_wn = Text__make_superlative(mdef->headword_wn);
{
#line 367 "inform7/Chapter 17/Measurement Adjectives.w"
TEMPORARY_STREAM;
STREAM_WRITE(TEMP, " To decide which object is %s ( S - description of objects ) ",
Text__word_text(mdef->superlative_wn));
int x1 = lexer_wordcount;
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
int x2 = lexer_wordcount-1;
Parser__Sentences__make_node(x1, x2, ':', NULL);
CLOSE_TEMPORARY_STREAM;
}
#line 360 "inform7/Chapter 17/Measurement Adjectives.w"
;
{
#line 379 "inform7/Chapter 17/Measurement Adjectives.w"
TEMPORARY_STREAM;
STREAM_WRITE(TEMP, " (- {-primitive-definition:extremal%s",
Properties__Measurement__strict_comparison(mdef->region_shape));
Text__print_text_to_stream(mdef->pname_w1, mdef->pname_w2, TEMP);
STREAM_WRITE(TEMP, "} -) ");
int x1 = lexer_wordcount;
Text__feed_into_lexer(STREAM_TEXT(TEMP), FALSE, NULL);
int x2 = lexer_wordcount-1;
Parser__Sentences__make_node(x1, x2, '.', NULL);
CLOSE_TEMPORARY_STREAM;
}
#line 361 "inform7/Chapter 17/Measurement Adjectives.w"
;
Parser__Sentences__register_recently_lexed_phrases();
}
#line 275 "inform7/Chapter 17/Measurement Adjectives.w"
;
{
#line 393 "inform7/Chapter 17/Measurement Adjectives.w"
adjective_meaning *am = Semantics__Adjectives__Meanings__new(MEASUREMENT_KADJ,
STORE_POINTER_measurement_definition(mdef), q->word_ref1, q->word_ref2);
mdef->headword_as_adjective = am;
Semantics__Adjectives__Meanings__declare(am, adj_name_w1, adj_name_w2);
Semantics__Adjectives__Meanings__pass_task_to_support_routine(am, TEST_ADJECTIVE_TASK);
Semantics__Adjectives__Meanings__set_domain_from_word_range(am,
dom_name_w1, dom_name_w2);
}
#line 276 "inform7/Chapter 17/Measurement Adjectives.w"
;
return mdef->headword_as_adjective;
}
#line 404 "inform7/Chapter 17/Measurement Adjectives.w"
void Properties__Measurement__Adjectives__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 = Semantics__Adjectives__Meanings__set_i6_schema(
mdef->headword_as_adjective, TEST_ADJECTIVE_TASK, FALSE);
Code__Schemas__modify(sch, "MADJ_Test_%d(*1)", mdef->allocation_id);
mdef->property_schema_written = TRUE;
}
}
int Properties__Measurement__Adjectives__compile(measurement_definition *mdef,
int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
int Properties__Measurement__Adjectives__assert(measurement_definition *mdef,
inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) {
validate_mdef(mdef);
if ((mdef_is_valid(mdef)) && (mdef->prop) && (parity == TRUE)) {
specification *val = Specifications__Values__new_actual_CONSTANT(
Properties__Valued__kind(mdef->prop));
val->word_ref1 = mdef->region_threshold_w1;
val->word_ref2 = mdef->region_threshold_w2;
World__Inferences__draw_property(infs_to_assert_on, mdef->prop, val);
return TRUE;
}
return FALSE;
}
int Properties__Measurement__Adjectives__index(measurement_definition *mdef) {
return FALSE;
}
#line 441 "inform7/Chapter 17/Measurement Adjectives.w"
void Properties__Measurement__Adjectives__compile_MADJ_routines(OUTPUT_STREAM) {
measurement_definition *mdef;
LOOP_OVER(mdef, measurement_definition)
if (mdef->property_schema_written) {
OUT = Code__Routines__begin_numbered(OUT, "MADJ_Test_%d", mdef->allocation_id);
local_variable *lv = Code__LocalVariables__add_call_parameter(
Code__Frames__current_stack_frame(),
-1, -1,
Semantics__Adjectives__Meanings__get_domain(mdef->headword_as_adjective));
specification *var = Specifications__Storage__new_LOCAL_VARIABLE(-1, -1, lv);
specification *evaluated_prop = Specifications__Storage__new_PROPERTY_VALUE(
Properties__to_specification(mdef->prop), var);
specification *val = Specifications__Values__new_actual_CONSTANT(
Properties__Valued__kind(mdef->prop));
val->word_ref1 = mdef->region_threshold_w1;
val->word_ref2 = mdef->region_threshold_w2;
pcalc_prop *prop = Calculus__Atoms__binary_PREDICATE_new(
weak_comparison_bp(mdef->region_shape),
Calculus__Terms__new_constant(evaluated_prop),
Calculus__Terms__new_constant(val));
if (Calculus__Propositions__type_check(prop,
Calculus__Propositions__tc_problem_reporting(mdef->region_threshold_w1,
mdef->region_threshold_w2,
"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 = Code__Routines__end(OUT);
}
}
#line 479 "inform7/Chapter 17/Measurement Adjectives.w"
void Properties__Measurement__Adjectives__create_comparatives(void) {
measurement_definition *mdef;
LOOP_OVER(mdef, measurement_definition) {
validate_mdef(mdef);
if ((mdef_is_valid(mdef)) && (mdef->region_shape != MEASURE_T_EXACTLY)) {
int headword_wn = mdef->headword_wn; /* word number of, e.g., "tall" */
int comparative_form = Text__make_comparative(headword_wn); /* "taller" */
vocabulary_entry *quiddity =
Text__word(Text__make_quiddity(headword_wn)); /* "tallness" */
i6_schema *schema_to_compare_property_values;
{
#line 499 "inform7/Chapter 17/Measurement Adjectives.w"
char *identifier = Properties__get_translation(mdef->prop);
char *operation = Properties__Measurement__strict_comparison(mdef->region_shape);
schema_to_compare_property_values =
Code__Schemas__new("(*1.%s %s *2.%s)", identifier, operation, identifier);
}
#line 490 "inform7/Chapter 17/Measurement Adjectives.w"
;
{
#line 514 "inform7/Chapter 17/Measurement Adjectives.w"
binary_predicate *bp;
bp = Semantics__BPs__make_pair(PROPERTY_COMPARISON_KBP,
Semantics__BPs__Terms__new(NULL), Semantics__BPs__Terms__new(NULL),
Text__Vocabulary__get_exemplar(quiddity, FALSE), NULL, NULL, NULL,
schema_to_compare_property_values, Text__Words__lit_1(quiddity));
Semantics__BPs__set_comparison_details(bp, mdef->region_shape, mdef->prop);
Semantics__PrepositionUsage__register_comparative(comparative_form, bp);
}
#line 491 "inform7/Chapter 17/Measurement Adjectives.w"
;
}
}
}
#line 21 "inform7/Chapter 17/Comparative Relations.w"
void Properties__Valued__Relations__Comparative__create_initial_stock(void) {
}
#line 35 "inform7/Chapter 17/Comparative Relations.w"
void Properties__Valued__Relations__Comparative__create_second_stock(void) {
Properties__Measurement__Adjectives__create_comparatives();
}
#line 45 "inform7/Chapter 17/Comparative Relations.w"
int Properties__Valued__Relations__Comparative__typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
if ((kinds_required[0]) &&
(Kinds__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__issue_bp_typecheck_error(bp,
kinds_of_terms[0], kinds_of_terms[1], tck);
return NEVER_MATCH;
}
property *prn = Kinds__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__tcp_problem(_P_(C17ComparativeMisapplied), tck,
"that ought to make a comparison of %4 not %5.");
return NEVER_MATCH;
}
return ALWAYS_MATCH;
}
#line 72 "inform7/Chapter 17/Comparative Relations.w"
int Properties__Valued__Relations__Comparative__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
return FALSE;
}
#line 82 "inform7/Chapter 17/Comparative Relations.w"
int Properties__Valued__Relations__Comparative__compile(int task, binary_predicate *bp,
annotated_i6_schema *asch) {
if (task == TEST_ATOM_TASK)
{
#line 98 "inform7/Chapter 17/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__eq(st[0], st[1]) == FALSE) &&
(Kinds__name_can_coincide_with_property(st[1]))) {
property *prn = Kinds__get_coinciding_property(st[1]);
if (prn) {
Code__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 17/Comparative Relations.w"
;
return FALSE;
}
#line 115 "inform7/Chapter 17/Comparative Relations.w"
int Properties__Valued__Relations__Comparative__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 13 "inform7/Chapter 17/Value-Property Relations.w"
void Properties__Valued__Relations__Setting__create_initial_stock(void) {
}
void Properties__Valued__Relations__Same__create_initial_stock(void) {
}
#line 27 "inform7/Chapter 17/Value-Property Relations.w"
binary_predicate *Properties__Valued__Relations__make_set_property_BP(int w1, int w2) {
binary_predicate *bp = Semantics__BPs__make_pair(PROPERTY_SETTING_KBP,
Semantics__BPs__Terms__new(Kinds__as_subject(K_object)),
Semantics__BPs__Terms__new(NULL),
"set-property", NULL, NULL, NULL, NULL, Text__Words__lit_0());
bp->property_pending_w1 = w1;
bp->property_pending_w2 = w2;
bp->reversal->property_pending_w1 = w1;
bp->reversal->property_pending_w2 = w2;
return bp;
}
#line 44 "inform7/Chapter 17/Value-Property Relations.w"
binary_predicate *Properties__Valued__Relations__find_set_property_BP(int w1, int w2) {
binary_predicate *bp;
LOOP_OVER(bp, binary_predicate)
if (Text__compare_word_range(w1, w2, bp->property_pending_w1, bp->property_pending_w2))
if (bp->right_way_round)
return bp;
return NULL;
}
#line 57 "inform7/Chapter 17/Value-Property Relations.w"
void Properties__Valued__Relations__fix_property_bp(binary_predicate *bp) {
binary_predicate *bpr = bp->reversal;
int w1 = bp->property_pending_w1, w2 = bp->property_pending_w2;
if (w1 < 0) return;
bp->property_pending_w1 = -1; bp->property_pending_w2 = -1;
bpr->property_pending_w1 = -1; bpr->property_pending_w2 = -1;
current_sentence = bp->bp_created_at;
parse_nt_against_word_range(relation_property_name_NTM, w1, w2, 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) set_property_BP_schemas(bp, prn);
else set_property_BP_schemas(bpr, prn);
}
#line 79 "inform7/Chapter 17/Value-Property Relations.w"
int relation_property_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 87 "inform7/Chapter 17/Value-Property Relations.w"
*X = FALSE;
Problems__sentence_problem(_P_(C17RelationWithEitherOrProperty),
"verbs can only set properties with values",
"not either/or properties like this one.");
}
#line 80 "inform7/Chapter 17/Value-Property Relations.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 95 "inform7/Chapter 17/Value-Property Relations.w"
*X = FALSE;
Problems__sentence_problem(_P_(C17RelationWithBadProperty),
"that doesn't seem to be a property",
"perhaps because you haven't defined it yet?");
}
#line 82 "inform7/Chapter 17/Value-Property Relations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 83 "inform7/Chapter 17/Value-Property Relations.w"
#line 104 "inform7/Chapter 17/Value-Property Relations.w"
binary_predicate *Properties__Valued__Relations__make_set_nameless_property_BP(property *prn) {
binary_predicate *bp = Properties__Valued__Relations__make_set_property_BP(-1, -1);
binary_predicate *bpr = bp->reversal;
bp->set_property = prn; bpr->set_property = prn;
set_property_BP_schemas(bp, prn);
return bp;
}
#line 117 "inform7/Chapter 17/Value-Property Relations.w"
void Properties__Valued__Relations__Setting__create_second_stock(void) {
binary_predicate *bp;
LOOP_OVER(bp, binary_predicate)
if (bp->property_pending_w1 >= 0)
Properties__Valued__Relations__fix_property_bp(bp);
}
#line 131 "inform7/Chapter 17/Value-Property Relations.w"
void set_property_BP_schemas(binary_predicate *bp, property *prn) {
bp->test_function =
Code__Schemas__new("*1.%s == *2", Properties__get_translation(prn));
bp->make_true_function =
Code__Schemas__new("*1.%s = *2", Properties__get_translation(prn));
Semantics__BPs__Terms__set_domain(&(bp->term_details[1]),
Properties__Valued__kind(prn));
}
#line 158 "inform7/Chapter 17/Value-Property Relations.w"
void Properties__Valued__Relations__Same__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 196 "inform7/Chapter 17/Value-Property Relations.w"
int w1 = prn->word_ref1, w2 = prn->word_ref2;
int i7_name_wn = lexer_wordcount;
char i7_name[STRING_TOLERANCE_LIMIT + 10];
sprintf(i7_name, "same-");
Text__print_modest_sized_text_to_string(w1, w2, i7_name + Platform__strlen(i7_name));
sprintf(i7_name + Platform__strlen(i7_name), "-as");
int i; for (i=0; i7_name[i]; i++) if (i7_name[i] == ' ') i7_name[i] = '-';
Text__feed_into_lexer(i7_name, TRUE, NULL);
rel_name = Text__word(i7_name_wn);
}
#line 164 "inform7/Chapter 17/Value-Property Relations.w"
;
binary_predicate *bp = Semantics__BPs__make_pair(PROPERTY_SAME_KBP,
Semantics__BPs__Terms__new(NULL), Semantics__BPs__Terms__new(NULL),
Text__Vocabulary__get_exemplar(rel_name, FALSE), NULL, NULL,
Code__Schemas__new("*1.%s = *2.%s", i6_pname, i6_pname),
Code__Schemas__new("*1.%s == *2.%s", i6_pname, i6_pname),
Text__Words__lit_1(rel_name));
bp->same_property = prn;
Semantics__PrepositionUsage__register_same_property_as(bp);
}
}
}
#line 219 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Setting__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 240 "inform7/Chapter 17/Value-Property Relations.w"
int safe = FALSE;
int compatible = Kinds__compatible(kinds_of_terms[1], val_kind);
if (compatible == ALWAYS_MATCH) safe = TRUE;
if (compatible == SOMETIMES_MATCH) {
if ((Kinds__le(val_kind, K_object) == FALSE) ||
(Kinds__eq(val_kind, K_direction)) ||
(Kinds__eq(val_kind, K_room)) ||
(Kinds__eq(val_kind, K_container)) ||
(Kinds__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__tcp_problem(_P_(C17PropertiesEquated), 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__tcp_problem(_P_(C17UnknownPropertyType), tck,
"that tries to set the value of an unknown property to %4.");
else
Problems__tcp_problem(_P_(C17PropertyType), 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 223 "inform7/Chapter 17/Value-Property Relations.w"
;
{
#line 275 "inform7/Chapter 17/Value-Property Relations.w"
if (Kinds__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__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 224 "inform7/Chapter 17/Value-Property Relations.w"
;
return ALWAYS_MATCH;
}
#line 290 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Same__typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
return DECLINE_TO_MATCH;
}
#line 298 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Setting__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
World__Inferences__draw_property(infs0, bp->set_property, spec1);
return TRUE;
}
int Properties__Valued__Relations__Same__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
return FALSE;
}
#line 315 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Setting__compile(int task,
binary_predicate *bp, annotated_i6_schema *asch) {
return FALSE;
}
int Properties__Valued__Relations__Same__compile(int task,
binary_predicate *bp, annotated_i6_schema *asch) {
return FALSE;
}
#line 328 "inform7/Chapter 17/Value-Property Relations.w"
property *Properties__Valued__Relations__bp_get_same_as_property(binary_predicate *bp) {
return bp->same_property;
}
int Properties__Valued__Relations__bp_sets_a_property(binary_predicate *bp) {
if ((bp->set_property) || (bp->property_pending_w1 >= 0)) return TRUE;
return FALSE;
}
#line 339 "inform7/Chapter 17/Value-Property Relations.w"
int Properties__Valued__Relations__Setting__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
int Properties__Valued__Relations__Same__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 102 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__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 17/Properties of Objects.w"
property_permission *pp;
LOOP_OVER_PERMISSIONS_FOR_PROPERTY(pp, prn) {
inference_subject *infs = World__Permissions__get_subject(pp);
if ((World__Subjects__is_an_object(infs) == FALSE) &&
(World__Subjects__is_a_kind_of_object(infs) == FALSE))
make_attribute = FALSE;
}
}
#line 109 "inform7/Chapter 17/Properties of Objects.w"
;
{
#line 141 "inform7/Chapter 17/Properties of Objects.w"
if (Properties__has_been_translated(prn)) make_attribute = TRUE;
}
#line 110 "inform7/Chapter 17/Properties of Objects.w"
;
{
#line 154 "inform7/Chapter 17/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 17/Properties of Objects.w"
;
Properties__EitherOr__implement_as_attribute(prn, make_attribute);
}
}
}
#line 166 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__compile_attributes(OUTPUT_STREAM) {
{
#line 176 "inform7/Chapter 17/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 17/Properties of Objects.w"
;
{
#line 203 "inform7/Chapter 17/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 17/Properties of Objects.w"
;
{
#line 228 "inform7/Chapter 17/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 17/Properties of Objects.w"
;
}
#line 250 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__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__Implementation__OfObjects__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 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__place_objects_in_definition_sequence(void) {
Properties__Implementation__OfObjects__begin_sequencing_objects();
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
Properties__Implementation__OfObjects__place_this_object_next(I);
}
#line 300 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__compile_all(OUTPUT_STREAM) {
instance *I;
Properties__Implementation__OfObjects__compile_subject(OUT,
Kinds__as_subject(K_object));
compile_class_definitions(OUT, Kinds__as_subject(K_object));
LOOP_OVER_OBJECTS_IN_COMPILATION_SEQUENCE(I)
Properties__Implementation__OfObjects__compile_subject(OUT,
Data__Instances__as_subject(I));
Plugins__Naming__compile_small_names(OUT);
}
void compile_class_definitions(OUTPUT_STREAM, inference_subject *within) {
inference_subject *subj;
LOOP_OVER(subj, inference_subject)
if ((World__Subjects__narrowest_broader_subject(subj) == within) &&
(World__Subjects__is_a_kind_of_object(subj))) {
Properties__Implementation__OfObjects__compile_subject(OUT, subj);
compile_class_definitions(OUT, subj);
}
}
#line 324 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__compile_subject(OUTPUT_STREAM, inference_subject *subj) {
LOGIF(OBJECT_COMPILATION, "Compiling object definition for $j\n", subj);
int words_used = 0;
kind *K = World__Subjects__as_kind(subj);
if (K) Config__Plugins__Call__estimate_property_usage(K, &words_used);
{
#line 355 "inform7/Chapter 17/Properties of Objects.w"
{
#line 374 "inform7/Chapter 17/Properties of Objects.w"
if (K) {
WRITE("Class %s ", Kinds__I6_classname(K));
} else {
instance *I = World__Subjects__as_instance(subj);
if (Config__Plugins__Call__compile_object_header(OUT, I) == FALSE) {
WRITE("Object ");
int i; for (i=0; i<Plugins__Spatial__get_definition_depth(I); i++) WRITE("-> ");
WRITE("%s \"\"", Data__Instances__identifier(I));
}
}
WRITE("\n");
}
#line 355 "inform7/Chapter 17/Properties of Objects.w"
;
INDENT;
{
#line 390 "inform7/Chapter 17/Properties of Objects.w"
inference_subject *sup = World__Subjects__narrowest_broader_subject(subj);
kind *S = World__Subjects__as_kind(sup);
if (Kinds__le(S, K_object)) {
WRITE("class %s\n", Kinds__I6_classname(S));
words_used++;
}
}
#line 357 "inform7/Chapter 17/Properties of Objects.w"
;
{
#line 402 "inform7/Chapter 17/Properties of Objects.w"
if (subj) Config__Inclusions__compile_inclusions_for_subject(OUT, subj);
}
#line 358 "inform7/Chapter 17/Properties of Objects.w"
;
Properties__Traverse__begin();
{
#line 413 "inform7/Chapter 17/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 += compile_property_within_object_body(OUT, subj, prn);
}
}
#line 360 "inform7/Chapter 17/Properties of Objects.w"
;
{
#line 425 "inform7/Chapter 17/Properties of Objects.w"
inference_subject *infs;
for (infs = subj; infs; infs = World__Subjects__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__uses_pointer_values(Properties__Valued__kind(prn))))
words_used += compile_property_within_object_body(OUT, subj, prn);
}
}
}
#line 361 "inform7/Chapter 17/Properties of Objects.w"
;
OUTDENT;
WRITE(";\n\n");
}
#line 329 "inform7/Chapter 17/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 = World__Subjects__narrowest_broader_subject(infs)) {
kind *K2 = World__Subjects__as_kind(infs);
if (K2) nw += World__Compile__get_rough_memory_usage(K2);
}
nw += 16;
int w1, w2;
Kinds__get_name(K, &w1, &w2, FALSE);
Code__VirtualMachines__note_usage("object", w1, w2, NULL, nw, 0, TRUE);
LOGIF(OBJECT_COMPILATION, "Rough size estimate: %d words\n", nw);
}
LOGIF(OBJECT_COMPILATION, "Compilation of $j complete\n", subj);
}
#line 440 "inform7/Chapter 17/Properties of Objects.w"
int compile_property_within_object_body(OUTPUT_STREAM, inference_subject *know, property *prn) {
int storage_cost = 0;
if ((Properties__Traverse__visited(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 470 "inform7/Chapter 17/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 448 "inform7/Chapter 17/Properties of Objects.w"
;
CLOSE_TEMPORARY_STREAM;
}
return storage_cost;
}
#line 495 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__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 528 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__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 547 "inform7/Chapter 17/Properties of Objects.w"
WRITE("\"");
if (prn->word_ref1 >= 0) Text__print_text_to_stream(prn->word_ref1, prn->word_ref2, OUT);
else WRITE("<nameless>");
WRITE("\" ");
pos++;
}
#line 537 "inform7/Chapter 17/Properties of Objects.w"
;
{
#line 569 "inform7/Chapter 17/Properties of Objects.w"
property *equiv;
LOOP_OVER(equiv, property)
if (strcmp(Properties__get_translation(equiv), run_time_id) == 0) {
{
#line 579 "inform7/Chapter 17/Properties of Objects.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__lt(K, K_object))
if (World__Permissions__find(Kinds__as_subject(K), equiv, FALSE)) {
WRITE("%s ", Kinds__I6_classname(K));
pos++;
}
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (World__Permissions__find(Data__Instances__as_subject(I), equiv, FALSE)) {
WRITE("%s ", Data__Instances__identifier(I));
pos++;
}
}
#line 572 "inform7/Chapter 17/Properties of Objects.w"
;
{
#line 596 "inform7/Chapter 17/Properties of Objects.w"
if (World__Permissions__find(Kinds__as_subject(K_object), equiv, FALSE)) {
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__eq(Kinds__super(K), K_object)) {
WRITE("%s ", Kinds__I6_classname(K));
pos++;
}
}
}
#line 573 "inform7/Chapter 17/Properties of Objects.w"
;
}
}
#line 538 "inform7/Chapter 17/Properties of Objects.w"
;
WRITE("NULL\n"); pos++;
}
OUTDENT; WRITE(";\n");
}
#line 615 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__CreatePropertyOffsets_routine(OUTPUT_STREAM) {
OUT = Code__Routines__begin(OUT, "CreatePropertyOffsets");
Code__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 637 "inform7/Chapter 17/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 627 "inform7/Chapter 17/Properties of Objects.w"
else
{
#line 647 "inform7/Chapter 17/Properties of Objects.w"
WRITE("valued_property_offsets-->%s = %d;\n", name, offset);
}
#line 628 "inform7/Chapter 17/Properties of Objects.w"
;
}
OUT = Code__Routines__end(OUT);
}
#line 660 "inform7/Chapter 17/Properties of Objects.w"
void Properties__Implementation__OfObjects__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 41 "inform7/Chapter 17/Properties of Values.w"
property_of_value_storage *Properties__Implementation__OfValues__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__Implementation__OfValues__pp_set_table_storage(int t, int i) {
if (latest_povs) {
latest_povs->storage_table_id = t;
latest_povs->storage_column_id = i;
}
}
#line 72 "inform7/Chapter 17/Properties of Values.w"
int KOV_representatives_compiled = FALSE;
void Properties__Implementation__OfValues__compile_properties(OUTPUT_STREAM, kind *K) {
if (KOV_representatives_compiled == FALSE) {
{
#line 90 "inform7/Chapter 17/Properties of Values.w"
WRITE("Class VPH_Class;\n");
}
#line 75 "inform7/Chapter 17/Properties of Values.w"
;
{
#line 99 "inform7/Chapter 17/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__RuntimeIDs__weak(K) == k_id) &&
(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 76 "inform7/Chapter 17/Properties of Values.w"
;
KOV_representatives_compiled = TRUE;
}
if (kind_has_a_vph(K)) {
{
#line 120 "inform7/Chapter 17/Properties of Values.w"
kind_no_permitted_properties(OUT, FALSE, K);
}
#line 80 "inform7/Chapter 17/Properties of Values.w"
;
{
#line 139 "inform7/Chapter 17/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__get_name_in_template_code(K));
WRITE("Array KOVP_%d_P%d table ",
Kinds__RuntimeIDs__weak(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,
Data__Instances__as_subject(nc), prn);
WRITE(") ");
}
WRITE(";\n");
}
}
#line 81 "inform7/Chapter 17/Properties of Values.w"
;
}
}
#line 160 "inform7/Chapter 17/Properties of Values.w"
int kind_has_a_vph(kind *K) {
if ((Kinds__le(K, K_object) == FALSE) &&
(kind_no_permitted_properties(NULL, TRUE, K) > 0))
return TRUE;
return FALSE;
}
#line 186 "inform7/Chapter 17/Properties of Values.w"
int kind_no_permitted_properties(OUTPUT_STREAM, int count_only, kind *K) {
int count = 0;
if (count_only == FALSE)
{
#line 236 "inform7/Chapter 17/Properties of Values.w"
WRITE("VPH_Class ValuePropertyHolder_%d\n", Kinds__RuntimeIDs__weak(K));
INDENT;
int r = 0;
if ((Kinds__has_properties(K)) &&
(Kinds__le(K, K_object) == FALSE))
r = Kinds__get_highest_valid_value_as_integer(K);
WRITE("with value_range %d\n", r);
}
#line 189 "inform7/Chapter 17/Properties of Values.w"
;
property *prn;
property_permission *pp;
TRAVERSE_PERMITTED_COMPILABLE_PROPERTIES(prn, pp, K) {
count++;
if (count_only)
{
#line 211 "inform7/Chapter 17/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__handmade_problem(_P_(C17AnomalousProperty));
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 194 "inform7/Chapter 17/Properties of Values.w"
;
if (count_only == FALSE)
{
#line 255 "inform7/Chapter 17/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__RuntimeIDs__weak(K), prn->allocation_id);
WRITE("\n");
}
#line 195 "inform7/Chapter 17/Properties of Values.w"
;
}
if (count_only == FALSE)
{
#line 267 "inform7/Chapter 17/Properties of Values.w"
OUTDENT;
WRITE(";\n");
}
#line 197 "inform7/Chapter 17/Properties of Values.w"
;
return count;
}
#line 75 "inform7/Chapter 18/Introduction to the Model World.w"
void World__begin(void) {
model_world = World__Subjects__new_fundamental(NULL, "model-world");
nonlocal_variables = World__Subjects__new_fundamental(model_world, "global-variables");
global_constants = World__Subjects__new_fundamental(model_world, "global-constants");
relations = World__Subjects__new_fundamental(model_world, "relations");
}
#line 83 "inform7/Chapter 18/Inference Subjects.w"
int no_roots = 0;
void infs_initialise(inference_subject *infs,
general_pointer gp, int KOI, int cert, inference_subject *from, char *lname) {
if ((from == NULL) && (++no_roots > 1)) {
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;
Parser__Assertions__Assemblies__initialise_assemblies_data(&(infs->assemblies));
int i;
for (i=0; i<MAX_PLUGINS; i++) infs->plugin_subj[i] = NULL;
Config__Plugins__Call__new_subject_notify(infs);
}
#line 110 "inform7/Chapter 18/Inference Subjects.w"
inference_subject *World__Subjects__new_fundamental(inference_subject *from, char *lname) {
inference_subject *infs = CREATE(inference_subject);
infs_initialise(infs, NULL_GENERAL_POINTER, FUND_SUB, LIKELY_CE, from, lname);
return infs;
}
inference_subject *World__Subjects__new(inference_subject *from, int KOI,
general_pointer gp, int cert) {
inference_subject *infs = CREATE(inference_subject);
infs_initialise(infs, gp, KOI, cert, from, NULL);
return infs;
}
#line 129 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__renew(inference_subject *infs,
inference_subject *from, int KOI, general_pointer gp, int cert) {
infs_initialise(infs, gp, KOI, cert, from, NULL);
}
#line 139 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__alias_to_nonlocal_variable(inference_subject *infs, nonlocal_variable *q) {
infs->alias_variable = q;
}
int World__Subjects__aliased_but_diverted(inference_subject *infs) {
if (infs->alias_variable) {
inference_subject *vs =
Data__Instances__as_subject(
Specifications__Values__instance_of_CONSTANT_object_if_any(
Data__NonlocalVariables__get_initial_value(
infs->alias_variable)));
if ((vs) && (vs != infs)) return TRUE;
}
return FALSE;
}
#line 163 "inform7/Chapter 18/Inference Subjects.w"
int World__Subjects__is_within(inference_subject *smaller, inference_subject *larger) {
while (smaller) {
if (smaller == larger) return TRUE;
smaller = smaller->broader_than;
}
return FALSE;
}
int World__Subjects__is_strictly_within(inference_subject *subj, inference_subject *larger) {
if (subj == NULL) return FALSE;
return World__Subjects__is_within(subj->broader_than, larger);
}
#line 180 "inform7/Chapter 18/Inference Subjects.w"
inference_subject *World__Subjects__narrowest_broader_subject(inference_subject *narrow) {
if (narrow == NULL) return NULL;
return narrow->broader_than;
}
#line 191 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__falls_within(inference_subject *narrow, inference_subject *broad) {
if (World__Subjects__is_within(broad, narrow->broader_than) == FALSE)
internal_error("subject breadth change leads to inconsistency");
narrow->broader_than = broad;
}
#line 201 "inform7/Chapter 18/Inference Subjects.w"
parse_node *World__Subjects__where_created(inference_subject *infs) {
if (infs == NULL) internal_error("null INFS");
return infs->infs_created_at;
}
int World__Subjects__get_default_certainty(inference_subject *infs) {
return infs->default_certainty;
}
assemblies_data *World__Subjects__get_assemblies_data(inference_subject *infs) {
if (infs == NULL) internal_error("tried to fetch assembly data for null subject");
return &(infs->assemblies);
}
inference *World__Subjects__get_inferences(inference_subject *infs) {
return (infs)?(infs->inf_list):NULL;
}
void World__Subjects__set_inferences(inference_subject *infs, inference *inf) {
if (infs == NULL) internal_error("null INFS");
infs->inf_list = inf;
}
implication *World__Subjects__get_implications(inference_subject *infs) {
return infs->imp_list;
}
void World__Subjects__set_implications(inference_subject *infs, implication *imp) {
infs->imp_list = imp;
}
property_permission **World__Subjects__get_permissions(inference_subject *infs) {
return &(infs->permissions_list);
}
#line 241 "inform7/Chapter 18/Inference Subjects.w"
inference_subject *World__Subjects__from_specification(specification *spec) {
inference_subject *infs = NULL;
if ((Specifications__species_is(spec, DESCRIPTION_SPC)) &&
(Specifications__Conditions__is_qualified_DESCRIPTION(spec) == FALSE) &&
(Specifications__Conditions__get_described_kind(spec))) {
kind *K = Specifications__Conditions__get_described_kind(spec);
infs = Kinds__as_subject(K);
} else if (Specifications__Values__is_generic_CONSTANT(spec)) {
kind *K = Specifications__get_kind(spec);
infs = Kinds__as_subject(K);
} else {
instance *I = Specifications__Values__instance_of_CONSTANT_object_if_any(spec);
if (I) infs = Data__Instances__as_subject(I);
else {
instance *nc = Specifications__Values__get_named_constant_if_any(spec);
if (nc) infs = Data__Instances__as_subject(nc);
}
}
return infs;
}
#line 272 "inform7/Chapter 18/Inference Subjects.w"
specification *World__Subjects__as_constant(inference_subject *infs) {
kind *K = World__Subjects__domain(infs);
if (K) return Specifications__Values__new_generic_CONSTANT(K);
instance *I = World__Subjects__as_instance(infs);
if (I) return Data__Instances__get_value(I);
instance *nc = World__Subjects__as_nc(infs);
if (nc) return Data__Instances__get_value(nc);
return NULL;
}
#line 288 "inform7/Chapter 18/Inference Subjects.w"
instance *World__Subjects__as_instance(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == INST_SUB)) {
instance *nc = RETRIEVE_POINTER_instance(infs->represents);
if (Kinds__le(Data__Instances__kind(nc), K_object))
return nc;
}
return NULL;
}
kind *World__Subjects__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__lt(K, K_object)) return NULL;
return K;
}
return NULL;
}
kind *World__Subjects__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 *World__Subjects__as_nlv(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == VARI_SUB))
return RETRIEVE_POINTER_nonlocal_variable(infs->represents);
return NULL;
}
binary_predicate *World__Subjects__as_bp(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == RELN_SUB))
return RETRIEVE_POINTER_binary_predicate(infs->represents);
return NULL;
}
instance *World__Subjects__as_nc(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == INST_SUB))
return RETRIEVE_POINTER_instance(infs->represents);
return NULL;
}
#line 337 "inform7/Chapter 18/Inference Subjects.w"
int World__Subjects__is_an_object(inference_subject *infs) {
if (World__Subjects__as_instance(infs)) return TRUE;
return FALSE;
}
int World__Subjects__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__lt(K, K_object)) return TRUE;
}
return FALSE;
}
#line 355 "inform7/Chapter 18/Inference Subjects.w"
kind *World__Subjects__domain(inference_subject *infs) {
return World__Subjects__as_kind(infs);
}
#line 362 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__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; }
int w1, w2;
World__Subjects__get_name_text(infs, &w1, &w2);
if (w1 >= 0) { LOG("infs'$W'", w1, w2); return; }
kind *K = World__Subjects__as_nonobject_kind(infs);
if (K) { LOG("infs'$u'", K); return; }
binary_predicate *bp = World__Subjects__as_bp(infs);
if (bp) { LOG("infs'%s'", Semantics__BPs__get_log_name(bp)); }
LOG("infs%d", infs->allocation_id);
}
void log_knowledge_about(inference_subject *infs) {
inference *inf;
LOG("Inferences drawn about $j:\n", infs); LOG_INDENT;
for (inf = World__Subjects__get_inferences(infs); inf; inf = inf->next) LOG("$I\n", inf);
LOG_OUTDENT;
}
#line 393 "inform7/Chapter 18/Inference Subjects.w"
void log_infs_hierarchy(void) {
LOG("Subjects hierarchy:\n");
log_subjects_hierarchically(NULL, 0);
}
void 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;
log_subjects_hierarchically(narrower, count+1);
LOG_OUTDENT;
}
}
#line 415 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__get_name_text(inference_subject *infs, int *w1, int *w2) {
if (infs == NULL) internal_error("null INFS");
*w1 = -1; *w2 = -1;
switch (infs->kind_of_infs) {
case FUND_SUB: break;
case KIND_SUB: Kinds__Subjects__get_name_text(infs, w1, w2); break;
case INST_SUB: Data__Instances__Subjects__get_name_text(infs, w1, w2); break;
case VARI_SUB: Data__NonlocalVariables__Subjects__get_name_text(infs, w1, w2); break;
case RELN_SUB: Semantics__BPs__Subjects__get_name_text(infs, w1, w2); break;
}
int i = *w1;
for (i = *w1; ((i>=0) && (i<=*w2)); i++)
if (Text__word(i) == STROKE_V) { *w2 = i-1; break; }
}
#line 436 "inform7/Chapter 18/Inference Subjects.w"
general_pointer World__Subjects__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__Subjects__new_permission_granted(infs);
case INST_SUB: return Data__Instances__Subjects__new_permission_granted(infs);
case VARI_SUB: return Data__NonlocalVariables__Subjects__new_permission_granted(infs);
case RELN_SUB: return Semantics__BPs__Subjects__new_permission_granted(infs);
}
return NULL_GENERAL_POINTER;
}
#line 454 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__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__Subjects__make_adj_const_domain(infs, nc, prn); break;
case INST_SUB: Data__Instances__Subjects__make_adj_const_domain(infs, nc, prn); break;
case VARI_SUB: Data__NonlocalVariables__Subjects__make_adj_const_domain(infs, nc, prn); break;
case RELN_SUB: Semantics__BPs__Subjects__make_adj_const_domain(infs, nc, prn); break;
}
}
#line 471 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__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__Subjects__complete_model(infs); break;
case INST_SUB: Data__Instances__Subjects__complete_model(infs); break;
case VARI_SUB: Data__NonlocalVariables__Subjects__complete_model(infs); break;
case RELN_SUB: Semantics__BPs__Subjects__complete_model(infs); break;
}
}
#line 486 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__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__Subjects__check_model(infs); break;
case INST_SUB: Data__Instances__Subjects__check_model(infs); break;
case VARI_SUB: Data__NonlocalVariables__Subjects__check_model(infs); break;
case RELN_SUB: Semantics__BPs__Subjects__check_model(infs); break;
}
}
#line 506 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__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__Subjects__write_element_of_condition(infs, cond); break;
case INST_SUB: Data__Instances__Subjects__write_element_of_condition(infs, cond); break;
case VARI_SUB: Data__NonlocalVariables__Subjects__write_element_of_condition(infs, cond); break;
case RELN_SUB: Semantics__BPs__Subjects__write_element_of_condition(infs, cond); break;
}
}
#line 528 "inform7/Chapter 18/Inference Subjects.w"
void World__Subjects__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__Subjects__compile_all(OUT); break;
case INST_SUB: done = Data__Instances__Subjects__compile_all(OUT); break;
case VARI_SUB: done = Data__NonlocalVariables__Subjects__compile_all(OUT); break;
case RELN_SUB: done = Semantics__BPs__Subjects__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__Subjects__compile(OUT, infs); break;
case INST_SUB: Data__Instances__Subjects__compile(OUT, infs); break;
case VARI_SUB: Data__NonlocalVariables__Subjects__compile(OUT, infs); break;
case RELN_SUB: Semantics__BPs__Subjects__compile(OUT, infs); break;
}
}
}
}
#line 114 "inform7/Chapter 18/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)?(World__Subjects__narrowest_broader_subject(infs)):NULL;
}
return NULL;
}
#line 141 "inform7/Chapter 18/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 18/Property Permissions.w"
new_pp = CREATE(property_permission);
new_pp->where_granted = current_sentence;
new_pp->pp_storage_data = World__Subjects__new_permission_granted(infs);
}
#line 146 "inform7/Chapter 18/Property Permissions.w"
;
{
#line 164 "inform7/Chapter 18/Property Permissions.w"
new_pp->property_owner = infs;
property_permission **ppl = World__Subjects__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 18/Property Permissions.w"
;
{
#line 177 "inform7/Chapter 18/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 18/Property Permissions.w"
;
{
#line 190 "inform7/Chapter 18/Property Permissions.w"
int i;
for (i=0; i<MAX_PLUGINS; i++) new_pp->plugin_pp[i] = NULL;
Config__Plugins__Call__new_permission_notify(new_pp);
}
#line 149 "inform7/Chapter 18/Property Permissions.w"
;
}
return new_pp;
}
#line 199 "inform7/Chapter 18/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 18/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) {
int w1, w2;
World__Subjects__get_name_text(World__Permissions__get_subject(pp), &w1, &w2);
if (w1 >= 0) {
if (s == 1) ac++;
else {
INDEX("</i>");
Text__print_raw_text_to_stream(w1, w2, ifl);
INDEX("<i>");
ac--;
if (ac == 1) INDEX(" or ");
if (ac > 1) INDEX(", ");
}
}
}
}
}
#line 97 "inform7/Chapter 18/Inferences.w"
int inference_timer = 0;
inference *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 18/Inferences.w"
inference *create_property_inference(inference_subject *infs,
property *prn, specification *val) {
PROTECTED_MODEL_PROCEDURE;
inference *i = create_inference(PROPERTY_INF, prevailing_mood);
if (prevailing_mood == UNKNOWN_CE)
i->certainty = World__Subjects__get_default_certainty(infs);
i->inferred_property = prn;
i->inferred_property_value = val;
if (prn == NULL) internal_error("null property inference");
return i;
}
inference *create_relation_inference(inference_subject *infs0, inference_subject *infs1) {
PROTECTED_MODEL_PROCEDURE;
inference *i = create_inference(ARBITRARY_RELATION_INF, prevailing_mood);
i->infs_ref1 = divert_infs(infs0);
i->infs_ref2 = divert_infs(infs1);
return i;
}
inference *create_relation_inference_spec(specification *spec0, specification *spec1) {
PROTECTED_MODEL_PROCEDURE;
inference *i = 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 18/Inferences.w"
void World__Inferences__draw_property(inference_subject *infs,
property *prn, specification *val) {
inference *i = create_property_inference(infs, prn, val);
join_inference(i, infs);
}
void World__Inferences__draw_negated_property(inference_subject *infs,
property *prn, specification *val) {
inference *i = create_property_inference(infs, prn, val);
i->certainty = -i->certainty;
join_inference(i, infs);
}
void World__Inferences__draw_relation(binary_predicate *bp,
inference_subject *infs0, inference_subject *infs1) {
inference *i = create_relation_inference(infs0, infs1);
join_inference(i, Semantics__BPs__as_subject(bp));
}
void World__Inferences__draw_relation_spec(binary_predicate *bp,
specification *spec0, specification *spec1) {
inference *i = create_relation_inference_spec(spec0, spec1);
join_inference(i, Semantics__BPs__as_subject(bp));
}
#line 187 "inform7/Chapter 18/Inferences.w"
void World__Inferences__draw(int type, inference_subject *about,
int certitude, inference_subject *infs0, inference_subject *infs1) {
inference *i = create_inference(type, certitude);
i->infs_ref1 = divert_infs(infs0); i->infs_ref2 = divert_infs(infs1);
join_inference(i, about);
}
#line 199 "inform7/Chapter 18/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;
}
specification *World__Inferences__get_property_value(inference *i) {
return i->inferred_property_value;
}
specification *World__Inferences__set_property_value_kind(inference *i, kind *K) {
Specifications__set_kind_of_value(i->inferred_property_value, K);
return i->inferred_property_value;
}
#line 241 "inform7/Chapter 18/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,
specification **spec1, specification **spec2) {
*spec1 = i->spec_ref1; *spec2 = i->spec_ref2;
}
instance *World__Inferences__get_reference_as_object(inference *i) {
return World__Subjects__as_instance(i->infs_ref1);
}
#line 271 "inform7/Chapter 18/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 = World__Subjects__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 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);
specification *val = World__Inferences__get_property_value(inf);
kind *PK = Properties__Valued__kind(prn);
kind *VK = Specifications__evaluates_to(val);
if (Kinds__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__handmade_problem(_P_(C18LateInferenceProblem));
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();
}
}
}
specification *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 = World__Subjects__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;
}
specification *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 = World__Subjects__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;
}
specification *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 18/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) {
specification *spec = World__Inferences__get_property_value(inf);
Index__dequote(Text__word_raw_text(spec->word_ref1));
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;
}
index_provided(infs, TRUE, c, cert, brief);
}
index_provided(infs, FALSE, LIKELY_CE, "Can have", brief);
}
#line 417 "inform7/Chapter 18/Inferences.w"
int 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 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 = has_or_can_have(infs, prn);
if (state != c) continue;
int inherited_state = has_or_can_have(
World__Subjects__narrowest_broader_subject(infs), prn);
if ((state == inherited_state) && (brief)) continue;
if (f) { INDEX("<i>%s</i> ", cert); f = FALSE; }
else INDEX(", ");
Text__print_raw_text_to_stream(prn->word_ref1, prn->word_ref2, ifl);
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> ");
Text__print_raw_text_to_stream(prnbar->word_ref1, prnbar->word_ref2, ifl);
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 18/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 = 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) Formats__HTML__open_para(ifl, 1, "hanging");
else INDEX("; ");
if (S < 0) INDEX("not ");
Text__print_raw_text_to_stream(prn->word_ref1, prn->word_ref2, ifl);
if (P) Index__link(P->word_ref1);
}
}
}
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;
specification *S = World__Inferences__get_prop_state_without_inheritance(infs, prn, &P);
if ((S) && (S->word_ref1 >= 0)) {
Formats__HTML__open_para(ifl, 1, "hanging");
Text__print_raw_text_to_stream(prn->word_ref1, prn->word_ref2, ifl);
INDEX(": <font color=\"#000080\">");
Text__print_raw_text_to_stream(S->word_ref1, S->word_ref2, ifl);
INDEX("</font>");
if (P) Index__link(P->word_ref1);
INDEX("</p>");
}
}
}
#line 547 "inform7/Chapter 18/Inferences.w"
int compare_inferences(inference *i1, inference *i2) {
pointer_sized_int c;
if (i1 == i2) return CI_IDENTICAL;
if (i1 == NULL) return CI_DIFFER_IN_EXISTENCE;
if (i2 == NULL) return -CI_DIFFER_IN_EXISTENCE;
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 = ((pointer_sized_int) pr1) - ((pointer_sized_int) pr2);
if (c > 0) return CI_DIFFER_IN_PROPERTY; if (c < 0) return -CI_DIFFER_IN_PROPERTY;
c = ((pointer_sized_int) i1->infs_ref2) - ((pointer_sized_int) i2->infs_ref2);
if (c > 0) return CI_DIFFER_IN_INFS2; if (c < 0) return -CI_DIFFER_IN_INFS2;
c = ((pointer_sized_int) i1->infs_ref1) - ((pointer_sized_int) i2->infs_ref1);
if (c > 0) return CI_DIFFER_IN_INFS1; if (c < 0) return -CI_DIFFER_IN_INFS1;
c = ((pointer_sized_int) i1->spec_ref2) - ((pointer_sized_int) i2->spec_ref2);
if (c > 0) return CI_DIFFER_IN_INFS2; if (c < 0) return -CI_DIFFER_IN_INFS2;
c = ((pointer_sized_int) i1->spec_ref1) - ((pointer_sized_int) i2->spec_ref1);
if (c > 0) return CI_DIFFER_IN_INFS1; if (c < 0) return -CI_DIFFER_IN_INFS1;
c = ((pointer_sized_int) i1) - ((pointer_sized_int) i2);
specification *val1 = i1->inferred_property_value;
specification *val2 = i2->inferred_property_value;
if ((i1->inferred_property != i2->inferred_property) ||
((val1) && (val2) && (Specifications__Values__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 *divert_infs(inference_subject *infs) {
if (infs_diversion)
if ((I_yourself) && (player_VAR) &&
(infs == Data__Instances__as_subject(I_yourself))) {
specification *val = Data__NonlocalVariables__get_initial_value(player_VAR);
inference_subject *divert = World__Subjects__from_specification(val);
if (divert) return divert;
}
return infs;
}
#line 612 "inform7/Chapter 18/Inferences.w"
void 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 = divert_infs(infs);
int inserted = FALSE;
inference *list, *prev;
for (prev = NULL, list = World__Subjects__get_inferences(infs);
(list) && (inserted == FALSE); prev = list, list = list->next) {
int c = 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 675 "inform7/Chapter 18/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 629 "inform7/Chapter 18/Inferences.w"
;
if (d >= affinity_threshold) {
{
#line 685 "inform7/Chapter 18/Inferences.w"
if (icl != lcl)
{
#line 700 "inform7/Chapter 18/Inferences.w"
if (lcl > icl) {
report_inference(i, infs, "discarded (we already know better)");
} else {
i->next = list->next;
if (prev == NULL) World__Subjects__set_inferences(infs, i); else prev->next = i;
report_inference(i, infs, "replaced existing less certain one");
}
}
#line 685 "inform7/Chapter 18/Inferences.w"
else {
int contradiction_flag = FALSE;
{
#line 721 "inform7/Chapter 18/Inferences.w"
switch (list->inference_type) {
case PROPERTY_INF:
if (d == CI_DIFFER_IN_PROPERTY_VALUE) contradiction_flag = TRUE;
break;
case ARBITRARY_RELATION_INF:
break;
default:
if (Config__Plugins__Call__inferences_contradict(list, i, d)) contradiction_flag = TRUE;
break;
}
if (list->certainty == -i->certainty) contradiction_flag = (contradiction_flag)?FALSE:TRUE;
}
#line 688 "inform7/Chapter 18/Inferences.w"
;
if (contradiction_flag) {
if (icl == CERTAIN_CE)
{
#line 737 "inform7/Chapter 18/Inferences.w"
report_inference(i, infs, "contradiction");
report_inference(list, infs, "with");
if ((list->inference_type != PROPERTY_INF) &&
(list->inference_type != ARBITRARY_RELATION_INF) &&
(Config__Plugins__Call__explain_contradiction(list, i, d, infs))) return;
if (i->inference_type == PROPERTY_INF) {
if (i->inferred_property == P_variable_initial_value)
Problems__two_sentences_problem(_P_(C18VariableContradiction),
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) {
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__handmade_problem(_P_(C18RelationContradiction));
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__two_sentences_problem(_P_(C18PropertyContradiction),
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
Problems__two_sentences_problem(_P_(C18Contradiction),
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 690 "inform7/Chapter 18/Inferences.w"
;
if ((icl == LIKELY_CE) && (World__Subjects__get_default_certainty(infs) == LIKELY_CE))
{
#line 792 "inform7/Chapter 18/Inferences.w"
i->next = list->next;
if (prev == NULL) World__Subjects__set_inferences(infs, i); else prev->next = i;
report_inference(i, infs, "replaced existing also only likely one");
return;
}
#line 692 "inform7/Chapter 18/Inferences.w"
;
}
report_inference(i, infs, "redundant");
}
}
#line 631 "inform7/Chapter 18/Inferences.w"
;
return;
}
if (c<0)
{
#line 648 "inform7/Chapter 18/Inferences.w"
if (prev == NULL) World__Subjects__set_inferences(infs, i); else prev->next = i;
i->next = list; inserted = TRUE;
}
#line 635 "inform7/Chapter 18/Inferences.w"
;
}
if (inserted == FALSE)
{
#line 648 "inform7/Chapter 18/Inferences.w"
if (prev == NULL) World__Subjects__set_inferences(infs, i); else prev->next = i;
i->next = list; inserted = TRUE;
}
#line 637 "inform7/Chapter 18/Inferences.w"
;
report_inference(i, infs, "drawn");
if (i->inference_type == PROPERTY_INF)
Config__Plugins__Call__property_value_notify(
i->inferred_property, i->inferred_property_value);
}
#line 803 "inform7/Chapter 18/Inferences.w"
void report_inference(inference *i, inference_subject *infs, char *what_happened) {
LOGIF(INFERENCES, ":::: %s: $j - $I\n", what_happened, infs, i);
}
#line 810 "inform7/Chapter 18/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: Config__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->word_ref1, in->inferred_property->word_ref2);
if (in->inferred_property_value) LOG("- 1:$S", in->inferred_property_value);
if (in->infs_ref1) LOG("- 1:$j", in->infs_ref1);
if (in->infs_ref2) LOG("- 2:$j", in->infs_ref2);
}
#line 54 "inform7/Chapter 18/Complete Model World.w"
void World__complete(void) {
Properties__Implementation__OfObjects__place_objects_in_definition_sequence();
model_world_under_construction = TRUE;
{
#line 73 "inform7/Chapter 18/Complete Model World.w"
inference_subject *infs;
LOOP_OVER(infs, inference_subject) {
World__Subjects__complete_model(infs);
Properties__Appearance__reallocate(infs);
}
LOOP_OVER(infs, inference_subject)
Parser__Assertions__Implications__consider_all(infs);
Config__Plugins__Call__complete_model(2);
Config__Plugins__Call__complete_model(3);
}
#line 59 "inform7/Chapter 18/Complete Model World.w"
;
{
#line 87 "inform7/Chapter 18/Complete Model World.w"
inference_subject *infs;
LOOP_OVER(infs, inference_subject) {
World__Subjects__check_model(infs);
{
#line 117 "inform7/Chapter 18/Complete Model World.w"
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
property *prn = World__Inferences__get_property(inf);
if (prn->word_ref1 >= 0)
if (World__Permissions__find(infs, prn, TRUE) == NULL)
Problems__inference_problem(_P_(C18PropertyNotPermitted),
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 18/Complete Model World.w"
;
{
#line 134 "inform7/Chapter 18/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 18/Complete Model World.w"
inference_subject *boss = World__Subjects__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 18/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) {
specification *narrow_val = World__Inferences__get_property_value(narrow);
specification *wide_val = World__Inferences__get_property_value(wide);
if (Specifications__Values__compare_CONSTANT(narrow_val, wide_val) == FALSE) {
LOG("Clash of $S and $S\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 18/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__infs_contradiction_problem(_P_(C18InstanceContradiction),
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 18/Complete Model World.w"
else
World__Inferences__set_certainty(narrow, IMPOSSIBLE_CE);
}
}
}
#line 158 "inform7/Chapter 18/Complete Model World.w"
;
boss = World__Subjects__narrowest_broader_subject(boss);
}
}
#line 140 "inform7/Chapter 18/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 18/Complete Model World.w"
inference_subject *boss = World__Subjects__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 18/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) {
specification *narrow_val = World__Inferences__get_property_value(narrow);
specification *wide_val = World__Inferences__get_property_value(wide);
if (Specifications__Values__compare_CONSTANT(narrow_val, wide_val) == FALSE) {
LOG("Clash of $S and $S\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 18/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__infs_contradiction_problem(_P_(C18InstanceContradiction),
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 18/Complete Model World.w"
else
World__Inferences__set_certainty(narrow, IMPOSSIBLE_CE);
}
}
}
#line 158 "inform7/Chapter 18/Complete Model World.w"
;
boss = World__Subjects__narrowest_broader_subject(boss);
}
}
#line 144 "inform7/Chapter 18/Complete Model World.w"
;
}
}
}
}
#line 91 "inform7/Chapter 18/Complete Model World.w"
;
}
Config__Plugins__Call__complete_model(4);
}
#line 60 "inform7/Chapter 18/Complete Model World.w"
;
model_world_under_construction = FALSE;
model_world_constructed = TRUE;
}
#line 210 "inform7/Chapter 18/Complete Model World.w"
void World__complete_additions(void) {
Config__Plugins__Call__complete_model(5);
}
#line 16 "inform7/Chapter 18/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 18/Compile Model World.w"
void World__Compile__compile(OUTPUT_STREAM) {
Config__Plugins__Call__compile_model_tables(OUT);
{
#line 46 "inform7/Chapter 18/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 18/Compile Model World.w"
;
World__Subjects__compile_all(OUT);
{
#line 54 "inform7/Chapter 18/Compile Model World.w"
Memory__I7_free(rough_array_memory_used, COMPILATION_SIZE_MREASON);
rough_array_memory_used = NULL;
}
#line 40 "inform7/Chapter 18/Compile Model World.w"
;
}
#line 39 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, naming_new_property_notify);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, naming_complete_model);
}
#line 50 "inform7/Chapter 18/The Naming Thicket.w"
int notable_naming_properties_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 61 "inform7/Chapter 18/The Naming Thicket.w"
#line 65 "inform7/Chapter 18/The Naming Thicket.w"
int naming_new_property_notify(property *prn) {
if (parse_nt_against_word_range(notable_naming_properties_NTM, prn->word_ref1, prn->word_ref2, 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 90 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__now_has_proper_name(inference_subject *infs) {
instance *wto = World__Subjects__as_instance(infs);
if (wto) Plugins__Naming__object_now_has_proper_name(wto);
}
void Plugins__Naming__object_now_has_proper_name(instance *I) {
if (P_proper_named)
Properties__EitherOr__assert(P_proper_named,
Data__Instances__as_subject(I), TRUE, LIKELY_CE);
}
void Plugins__Naming__object_now_has_plural_name(instance *I) {
if (P_plural_named)
Properties__EitherOr__assert(P_plural_named,
Data__Instances__as_subject(I), TRUE, LIKELY_CE);
}
#line 116 "inform7/Chapter 18/The Naming Thicket.w"
specification *text_of_word_the = NULL;
void Plugins__Naming__object_takes_definite_article(inference_subject *subj) {
if (text_of_word_the == NULL)
text_of_word_the = Specifications__Values__new_text_literal("\"the\"");
Properties__Valued__assert(P_article, subj, text_of_word_the, LIKELY_CE);
}
#line 128 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__transfer_details(inference_subject *from, inference_subject *to) {
instance *wto = World__Subjects__as_instance(to);
if (wto) {
if (World__Inferences__get_EO_state(from, P_proper_named) > 0)
Plugins__Naming__now_has_proper_name(to);
specification *art = World__Inferences__get_prop_state(from, P_article);
if (art) Properties__Valued__assert(P_article, to, art, LIKELY_CE);
}
}
instance *object_this_is_named_after(instance *I) {
return World__Subjects__as_instance(
Parser__Assertions__Assemblies__what_this_is_named_after(
Data__Instances__as_subject(I)));
}
#line 149 "inform7/Chapter 18/The Naming Thicket.w"
int Plugins__Naming__object_is_privately_named(instance *I) {
int certainty = World__Inferences__get_EO_state(Data__Instances__as_subject(I), P_privately_named);
if (certainty > 0) return TRUE;
if (certainty < 0) return FALSE;
return NOT_APPLICABLE;
}
#line 161 "inform7/Chapter 18/The Naming Thicket.w"
int naming_complete_model(int stage) {
if (stage == 3)
{
#line 170 "inform7/Chapter 18/The Naming Thicket.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__lt(K, K_object)) {
int w1, w2, pw1, pw2;
Kinds__get_name_in_play(K, &w1, &w2, FALSE);
Kinds__get_name_in_play(K, &pw1, &pw2, TRUE);
inference_subject *subj = Kinds__as_subject(K);
{
#line 219 "inform7/Chapter 18/The Naming Thicket.w"
int j;
for (j=w1; ((j>=0) && (j<=w2)); j++) {
if (Text__word(j) == COMMA_V) {
Problems__subject_creation_problem(_P_(C18CommaInName),
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 (Text__Vocabulary__test_flags(j, TEXT_MC+TEXTWITHSUBS_MC)) {
Problems__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 177 "inform7/Chapter 18/The Naming Thicket.w"
;
{
#line 396 "inform7/Chapter 18/The Naming Thicket.w"
if ((Kinds__le(K, K_room) == FALSE) &&
(Kinds__eq(K, K_thing) == FALSE) &&
(World__Inferences__get_prop_state_without_inheritance(
subj, P_printed_plural_name, NULL) == NULL)) {
if (pw1 >= 0) {
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");
compose_words_to_I6_naming_text(PROP, pw1, pw2, FALSE, TRUE);
Properties__Valued__assert(P_printed_plural_name, subj,
Specifications__Values__new_text_literal_from_stream(PROP), CERTAIN_CE);
}
}
}
#line 178 "inform7/Chapter 18/The Naming Thicket.w"
;
}
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
int w1, w2;
Data__Instances__get_name_in_play(I, &w1, &w2, FALSE);
inference_subject *subj = Data__Instances__as_subject(I);
int this_is_a_room = Plugins__Spatial__object_is_a_room(I);
int this_has_a_printed_name = look_for_printed_name(subj);
int this_is_named_for_something_with_a_printed_name = FALSE;
if (object_this_is_named_after(I))
if (look_for_printed_name(
Data__Instances__as_subject(object_this_is_named_after(I))))
this_is_named_for_something_with_a_printed_name = TRUE;
{
#line 219 "inform7/Chapter 18/The Naming Thicket.w"
int j;
for (j=w1; ((j>=0) && (j<=w2)); j++) {
if (Text__word(j) == COMMA_V) {
Problems__subject_creation_problem(_P_(C18CommaInName),
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 (Text__Vocabulary__test_flags(j, TEXT_MC+TEXTWITHSUBS_MC)) {
Problems__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 192 "inform7/Chapter 18/The Naming Thicket.w"
;
{
#line 205 "inform7/Chapter 18/The Naming Thicket.w"
if (P_list_together == NULL)
P_list_together = Properties__Valued__new_nameless(
"list_together", K_number);
specification *zero = Specifications__Values__new_integer_literal(0);
Properties__Valued__assert(P_list_together, subj,
zero, CERTAIN_CE);
}
#line 193 "inform7/Chapter 18/The Naming Thicket.w"
;
if (this_has_a_printed_name == FALSE)
{
#line 248 "inform7/Chapter 18/The Naming Thicket.w"
if (this_has_a_printed_name == FALSE) {
int w1, w2;
Data__Instances__get_name_in_play(I, &w1, &w2, FALSE);
if (w1 < 0) {
kind *k = Data__Instances__kind(I);
Kinds__get_name_in_play(k, &w1, &w2, FALSE);
}
int begins_with_lower_case = TRUE;
if (w1 >= 0) {
char *p = Text__word_raw_text(w1);
if (islower(p[0])) begins_with_lower_case = TRUE;
}
{
#line 267 "inform7/Chapter 18/The Naming Thicket.w"
int faux = FALSE;
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 333 "inform7/Chapter 18/The Naming Thicket.w"
faux = TRUE;
instance *owner = object_this_is_named_after(I);
STREAM_WRITE(PROP, "SN_R_A_%d", sn_r_counter);
{
#line 383 "inform7/Chapter 18/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 336 "inform7/Chapter 18/The Naming Thicket.w"
;
STREAM_WRITE(SNAMES, "Array SN_R_A_%d --> CONSTANT_PACKED_TEXT_STORAGE SN_R_%d;\n",
sn_r_counter, sn_r_counter);
SNAMES = Code__Routines__begin_numbered(SNAMES, "SN_R_%d", sn_r_counter++);
STREAM_WRITE(SNAMES, "print (name) %s, \"'s ",
Data__Instances__identifier(owner));
int j, n1, n2;
Parser__Assertions__Assemblies__get_named_after_text(subj, &n1, &n2);
if (n1 >= 0) {
for (j=n1; j<=n2; j++) {
Formats__Inform6__compile_string(SNAMES, Text__word_raw_text(j), 0);
if (j<n2) STREAM_WRITE(SNAMES, " ");
}
}
STREAM_WRITE(SNAMES, "\"; rtrue;");
SNAMES = Code__Routines__end(SNAMES);
}
#line 273 "inform7/Chapter 18/The Naming Thicket.w"
else
{
#line 319 "inform7/Chapter 18/The Naming Thicket.w"
compose_words_to_I6_naming_text(PROP, w1, w2, FALSE, (this_is_a_room)?FALSE:TRUE);
}
#line 274 "inform7/Chapter 18/The Naming Thicket.w"
;
if (faux)
Properties__Valued__assert(P_printed_name, subj,
Specifications__Values__faux_text_literal_from_stream(PROP), CERTAIN_CE);
else
Properties__Valued__assert(P_printed_name, subj,
Specifications__Values__new_text_literal_from_stream(PROP), CERTAIN_CE);
}
#line 260 "inform7/Chapter 18/The Naming Thicket.w"
;
{
#line 289 "inform7/Chapter 18/The Naming Thicket.w"
int set_csn = TRUE, faux = FALSE;
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 356 "inform7/Chapter 18/The Naming Thicket.w"
faux = TRUE;
instance *owner = object_this_is_named_after(I);
STREAM_WRITE(PROP, "SN_R_A_%d", sn_r_counter);
{
#line 383 "inform7/Chapter 18/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 359 "inform7/Chapter 18/The Naming Thicket.w"
;
STREAM_WRITE(SNAMES, "Array SN_R_A_%d --> CONSTANT_PACKED_TEXT_STORAGE SN_R_%d;\n",
sn_r_counter, sn_r_counter);
SNAMES = Code__Routines__begin_numbered(SNAMES, "SN_R_%d", sn_r_counter++);
STREAM_WRITE(SNAMES,
"if (%s.&cap_short_name) PrintOrRun(%s, cap_short_name, true);\n",
Data__Instances__identifier(owner),
Data__Instances__identifier(owner));
STREAM_WRITE(SNAMES,
"else PrintOrRun(%s, short_name, true);\n",
Data__Instances__identifier(owner));
STREAM_WRITE(SNAMES, "print \"'s ");
int j, n1, n2;
Parser__Assertions__Assemblies__get_named_after_text(subj, &n1, &n2);
for (j=n1; j<=n2; j++) {
Formats__Inform6__compile_string(SNAMES, Text__word_raw_text(j), 0);
if (j<n2) STREAM_WRITE(SNAMES, " ");
}
STREAM_WRITE(SNAMES, "\"; rtrue;");
SNAMES = Code__Routines__end(SNAMES);
}
#line 294 "inform7/Chapter 18/The Naming Thicket.w"
else {
if ((World__Inferences__get_EO_state(subj, P_proper_named) > 0)
&& (begins_with_lower_case))
{
#line 324 "inform7/Chapter 18/The Naming Thicket.w"
compose_words_to_I6_naming_text(PROP, w1, w2, TRUE, (this_is_a_room)?FALSE:TRUE);
}
#line 298 "inform7/Chapter 18/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 (faux)
Properties__Valued__assert(P_cap_short_name, subj,
Specifications__Values__faux_text_literal_from_stream(PROP), CERTAIN_CE);
else
Properties__Valued__assert(P_cap_short_name, subj,
Specifications__Values__new_text_literal_from_stream(PROP), CERTAIN_CE);
}
}
#line 261 "inform7/Chapter 18/The Naming Thicket.w"
;
}
}
#line 194 "inform7/Chapter 18/The Naming Thicket.w"
;
if (language_of_play != English_language)
{
#line 413 "inform7/Chapter 18/The Naming Thicket.w"
specification *spec = World__Inferences__get_prop_state(subj, P_grammatical_gender);
if (spec) {
int g = Specifications__get_data(spec, CONSTANT_ENUMERATION_SPDATA);
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 196 "inform7/Chapter 18/The Naming Thicket.w"
;
}
}
#line 162 "inform7/Chapter 18/The Naming Thicket.w"
;
return FALSE;
}
#line 439 "inform7/Chapter 18/The Naming Thicket.w"
int look_for_printed_name(inference_subject *subj) {
inference_subject *check;
for (check = subj; check; check = World__Subjects__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 455 "inform7/Chapter 18/The Naming Thicket.w"
void compose_words_to_I6_naming_text(OUTPUT_STREAM, int w1, int w2, int cap, int your_flag) {
WRITE("\"");
int j;
if (w1 >= 0) {
for (j=w1; j<=w2; j++) {
int your_here = parse_nt_against_word_range(possessive_second_person_NTM, j, j, NULL, NULL);
char *p = Text__word_raw_text(j);
if (cap) {
if ((j==w1) && (your_here) && (your_flag)) {
WRITE("%c", Platform__toupper(p[0]));
Formats__Inform6__compile_string(OUT, p+1, ISN_RAW);
} else if (j==w1) Formats__Inform6__compile_string(OUT, p, ISN_RAW + ISN_CAPITALISE);
else Formats__Inform6__compile_string(OUT, p, ISN_RAW);
} else {
if ((j==w1) && (your_here) && (your_flag)) {
WRITE("%c", Platform__tolower(p[0]));
Formats__Inform6__compile_string(OUT, p+1, ISN_RAW);
} else Formats__Inform6__compile_string(OUT, p, ISN_RAW);
}
if (j<w2) WRITE(" ");
}
} else {
if (cap) WRITE("Object"); else WRITE("object");
}
WRITE("\"");
}
#line 485 "inform7/Chapter 18/The Naming Thicket.w"
void Plugins__Naming__compile_small_names(OUTPUT_STREAM) {
if (SNAMES) {
STREAM_COPY(OUT, SNAMES);
STREAM_CLOSE(SNAMES);
}
}
#line 38 "inform7/Chapter 18/Instance Counting.w"
void Plugins__Counting__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_SUBJECT_NOTIFY, counting_new_subject_notify);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, counting_complete_model);
PLUGIN_REGISTER(PLUGIN_COMPILE_MODEL_TABLES, counting_compile_model_tables);
PLUGIN_REGISTER(PLUGIN_ESTIMATE_PROPERTY_USAGE, counting_estimate_property_usage);
}
#line 49 "inform7/Chapter 18/Instance Counting.w"
int counting_new_subject_notify(inference_subject *subj) {
CREATE_PF_DATA(counting, subj);
return FALSE;
}
counting_data *counting_plugin_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 18/Instance Counting.w"
int *kind_instance_counts = NULL;
int max_kind_instance_count = 0;
void make_instance_counts(void) {
{
#line 87 "inform7/Chapter 18/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 18/Instance Counting.w"
;
{
#line 96 "inform7/Chapter 18/Instance Counting.w"
instance *I;
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__lt(K, K_object))
LOOP_OVER_OBJECT_INSTANCES(I)
INSTANCE_COUNT(I, K) = -1;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__lt(K, K_object)) {
int ix_count = 0;
LOOP_OVER_INSTANCES(I, K)
INSTANCE_COUNT(I, K) = ix_count++;
}
}
#line 81 "inform7/Chapter 18/Instance Counting.w"
;
}
#line 113 "inform7/Chapter 18/Instance Counting.w"
int Plugins__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 18/Instance Counting.w"
instance *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 (World__Subjects__aliased_but_diverted(Data__Instances__as_subject(I)))
continue; /* |selfobj| may not count */
if (Data__Instances__of_kind(I, k)) return I;
}
return NULL;
}
#line 150 "inform7/Chapter 18/Instance Counting.w"
specification *next_instance_of_as_value(instance *I, kind *k) {
instance *next = next_instance_of(I, k);
if (next) return Data__Instances__get_value(next);
return Specifications__Values__new_nothing_object_constant();
}
#line 166 "inform7/Chapter 18/Instance Counting.w"
int counting_compile_model_tables(OUTPUT_STREAM) {
{
#line 183 "inform7/Chapter 18/Instance Counting.w"
WRITE("Array KindHierarchy --> K0_kind (0) ");
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__lt(K, K_object))
WRITE("%s (%d) ", Kinds__I6_classname(K),
kind_of_object_count(Kinds__super(K)));
WRITE(";\n");
}
#line 167 "inform7/Chapter 18/Instance Counting.w"
;
{
#line 196 "inform7/Chapter 18/Instance Counting.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__lt(K, K_object)) {
WRITE("Constant IK%d_First = ", Kinds__I6_classnumber(K));
Specifications__compile(OUT, next_instance_of_as_value(NULL, K));
WRITE(";\n");
}
}
#line 168 "inform7/Chapter 18/Instance Counting.w"
;
return FALSE;
}
#line 207 "inform7/Chapter 18/Instance Counting.w"
int kind_of_object_count(kind *K) {
int c = 0;
if (K == NULL) return 0;
kind *IK;
LOOP_OVER_BASE_KINDS(IK)
if (Kinds__lt(IK, K_object)) {
c++;
if (Kinds__eq(IK, K)) return c;
}
return 0;
}
#line 235 "inform7/Chapter 18/Instance Counting.w"
int counting_complete_model(int stage) {
if (stage == 1) {
{
#line 251 "inform7/Chapter 18/Instance Counting.w"
P_vector = Properties__Valued__new_nameless("vector", K_number);
specification *zero = Specifications__Values__new_integer_literal(0);
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
Properties__Valued__assert(P_vector,
Data__Instances__as_subject(I), zero, CERTAIN_CE);
}
#line 237 "inform7/Chapter 18/Instance Counting.w"
;
}
if (stage == 4) {
{
#line 261 "inform7/Chapter 18/Instance Counting.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__lt(K, K_object)) {
inference_subject *subj = Kinds__as_subject(K);
char pname[32];
sprintf(pname, "IK%d_Count", Kinds__I6_classnumber(K));
PF_S(counting, subj)->instance_count_prop =
Properties__Valued__new_nameless(pname, K_number);
sprintf(pname, "IK%d_Link", Kinds__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 18/Instance Counting.w"
;
make_instance_counts();
{
#line 278 "inform7/Chapter 18/Instance Counting.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
{
#line 305 "inform7/Chapter 18/Instance Counting.w"
int ic = kind_of_object_count(Data__Instances__kind(I));
specification *the_count = Specifications__Values__new_integer_literal(ic);
Properties__Valued__assert(
P_KD_Count, Data__Instances__as_subject(I), the_count, CERTAIN_CE);
}
#line 280 "inform7/Chapter 18/Instance Counting.w"
;
inference_subject *infs;
for (infs = Kinds__as_subject(Data__Instances__kind(I));
infs; infs = World__Subjects__narrowest_broader_subject(infs)) {
kind *K = World__Subjects__as_kind(infs);
if (Kinds__lt(K, K_object)) {
inference_subject *subj = Kinds__as_subject(K);
PF_S(counting, subj)->has_instances = TRUE;
{
#line 318 "inform7/Chapter 18/Instance Counting.w"
int ic = INSTANCE_COUNT(I, K);
specification *the_count = Specifications__Values__new_integer_literal(ic);
Properties__Valued__assert(
PF_S(counting, subj)->instance_count_prop,
Data__Instances__as_subject(I), the_count, CERTAIN_CE);
}
#line 288 "inform7/Chapter 18/Instance Counting.w"
;
{
#line 328 "inform7/Chapter 18/Instance Counting.w"
Properties__Valued__assert(
PF_S(counting, subj)->instance_link_prop,
Data__Instances__as_subject(I), next_instance_of_as_value(I, K), CERTAIN_CE);
}
#line 289 "inform7/Chapter 18/Instance Counting.w"
;
}
}
}
}
#line 242 "inform7/Chapter 18/Instance Counting.w"
;
}
return FALSE;
}
#line 337 "inform7/Chapter 18/Instance Counting.w"
int counting_estimate_property_usage(kind *k, int *words_used) {
inference_subject *infs;
for (infs = World__Subjects__narrowest_broader_subject(Kinds__as_subject(k));
infs; infs = World__Subjects__narrowest_broader_subject(infs)) {
kind *k2 = World__Subjects__as_kind(infs);
if (Kinds__lt(k2, K_object))
*words_used += 4;
}
return FALSE;
}
#line 354 "inform7/Chapter 18/Instance Counting.w"
int Plugins__Counting__optimise_loop(i6_schema *sch, kind *K) {
if (Config__Plugins__plugged_in(counting_plugin) == FALSE) return FALSE;
inference_subject *subj = Kinds__as_subject(K);
if (PF_S(counting, subj)->has_instances == FALSE) /* (to avoid writing misleading code) */
Code__Schemas__modify(sch,
"for (*1=nothing: false: )");
else
Code__Schemas__modify(sch,
"for (*1=IK%d_First: *1: *1=*1.IK%d_Link)",
Kinds__I6_classnumber(K), Kinds__I6_classnumber(K));
return TRUE;
}
#line 100 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, spatial_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_ACT_ON_SPECIAL_NPS, spatial_act_on_special_NPs);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, IF_complete_model);
PLUGIN_REGISTER(PLUGIN_DEFAULT_APPEARANCE, spatial_default_appearance);
PLUGIN_REGISTER(PLUGIN_INFERENCES_CONTRADICT, spatial_inferences_contradict);
PLUGIN_REGISTER(PLUGIN_EXPLAIN_CONTRADICTION, spatial_explain_contradiction);
PLUGIN_REGISTER(PLUGIN_LOG_INFERENCE_TYPE, spatial_log_inference_type);
PLUGIN_REGISTER(PLUGIN_NAME_TO_EARLY_INFS, spatial_name_to_early_infs);
PLUGIN_REGISTER(PLUGIN_NEW_SUBJECT_NOTIFY, spatial_new_subject_notify);
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, spatial_new_property_notify);
PLUGIN_REGISTER(PLUGIN_PARSE_COMPOSITE_NQS, spatial_parse_composite_NQs);
PLUGIN_REGISTER(PLUGIN_SET_KIND_NOTIFY, spatial_set_kind_notify);
PLUGIN_REGISTER(PLUGIN_SET_SUBKIND_NOTIFY, spatial_set_subkind_notify);
PLUGIN_REGISTER(PLUGIN_ADD_TO_WORLD_INDEX, spatial_add_to_World_index);
PLUGIN_REGISTER(PLUGIN_INTERVENE_IN_ASSERTION, spatial_intervene_in_assertion);
{
#line 138 "inform7/Chapter 19/Spatial Model.w"
infs_room = World__Subjects__new(global_constants,
FUND_SUB, NULL_GENERAL_POINTER, LIKELY_CE);
infs_thing = World__Subjects__new(global_constants,
FUND_SUB, NULL_GENERAL_POINTER, LIKELY_CE);
infs_supporter = World__Subjects__new(global_constants,
FUND_SUB, NULL_GENERAL_POINTER, LIKELY_CE);
infs_person = World__Subjects__new(global_constants,
FUND_SUB, NULL_GENERAL_POINTER, LIKELY_CE);
}
#line 116 "inform7/Chapter 19/Spatial Model.w"
;
}
#line 154 "inform7/Chapter 19/Spatial Model.w"
int spatial_name_to_early_infs(int w1, int w2, inference_subject **infs) {
if (parse_nt_against_word_range(notable_spatial_kinds_NTM, w1, w2, 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 19/Spatial Model.w"
spatial_data *spatial_plugin_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 19/Spatial Model.w"
int 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 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 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__handmade_problem(_P_(C19SpatialContradiction));
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 19/Spatial Model.w"
int notable_spatial_kinds_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 243 "inform7/Chapter 19/Spatial Model.w"
#line 247 "inform7/Chapter 19/Spatial Model.w"
int spatial_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) {
if (parse_nt_against_word_range(notable_spatial_kinds_NTM, w1, w2, 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 spatial_new_subject_notify(inference_subject *subj) {
CREATE_PF_DATA(spatial, subj);
return FALSE;
}
#line 270 "inform7/Chapter 19/Spatial Model.w"
int spatial_set_kind_notify(instance *I, kind *k) {
kind *kw = Data__Instances__kind(I);
if ((!(Kinds__le(kw, K_room))) &&
(Kinds__le(k, K_room)))
World__Inferences__draw(IS_ROOM_INF, Data__Instances__as_subject(I), CERTAIN_CE,
NULL, NULL);
return FALSE;
}
#line 283 "inform7/Chapter 19/Spatial Model.w"
int spatial_set_subkind_notify(kind *sub, kind *super) {
if ((sub == K_thing) && (super != K_object)) {
Problems__sentence_problem(_P_(C19ThingAdrift),
"'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)) {
Problems__sentence_problem(_P_(C19RoomAdrift),
"'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;
}
return FALSE;
}
#line 306 "inform7/Chapter 19/Spatial Model.w"
int Plugins__Spatial__object_is_a_room(instance *I) {
if ((Config__Plugins__plugged_in(spatial_plugin)) && (K_room) && (I) &&
(Data__Instances__of_kind(I, K_room)))
return TRUE;
return FALSE;
}
#line 317 "inform7/Chapter 19/Spatial Model.w"
void Plugins__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 335 "inform7/Chapter 19/Spatial Model.w"
int notable_spatial_properties_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 340 "inform7/Chapter 19/Spatial Model.w"
#line 344 "inform7/Chapter 19/Spatial Model.w"
int spatial_new_property_notify(property *prn) {
if (parse_nt_against_word_range(notable_spatial_properties_NTM, prn->word_ref1, prn->word_ref2, 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 365 "inform7/Chapter 19/Spatial Model.w"
int spatial_default_appearance(inference_subject *infs, specification *txt) {
if (World__Subjects__is_within(infs, Kinds__as_subject(K_object))) {
property *set_prn = P_description;
if (World__Subjects__is_within(infs, Kinds__as_subject(K_thing))) {
instance *I = World__Subjects__as_instance(infs);
if ((I) && (Plugins__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 394 "inform7/Chapter 19/Spatial Model.w"
Problems__object_problem(_P_(C19SceneryDoublyDescribed),
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 376 "inform7/Chapter 19/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 409 "inform7/Chapter 19/Spatial Model.w"
int spatial_specifying_nouns_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 419 "inform7/Chapter 19/Spatial Model.w"
#line 435 "inform7/Chapter 19/Spatial Model.w"
int spatial_parse_composite_NQs(int *w1, int *w2, int *determiner_w1, int *determiner_w2,
quantifier **quant, kind **some_kind) {
if (K_thing) {
quantifier_q_NTMV = NULL; kind_k_NTMV = NULL;
if (parse_nt_against_word_range(spatial_specifying_nouns_NTM, *w1, *w2, NULL, NULL)) {
int unwanted;
GET_RW(spatial_specifying_nouns_NTM, 1, *w1, unwanted);
*quant = quantifier_q_NTMV; *some_kind = kind_k_NTMV;
return TRUE;
}
}
return FALSE;
}
#line 454 "inform7/Chapter 19/Spatial Model.w"
int notable_spatial_noun_phrases_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 456 "inform7/Chapter 19/Spatial Model.w"
#line 460 "inform7/Chapter 19/Spatial Model.w"
int spatial_act_on_special_NPs(parse_node *p) {
if ((parse_nt_against_word_range(notable_spatial_noun_phrases_NTM, p->word_ref1, p->word_ref2, NULL, NULL)) &&
(Text__unexpectedly_upper_case(p->word_ref1) == FALSE) &&
(K_room)) {
Parser__Nodes__noun_from_value(p, Specifications__Values__new_nothing_object_constant());
Parser__Nodes__annotate_int(p, nowhere_ANNOT, TRUE);
return TRUE;
}
return FALSE;
}
#line 474 "inform7/Chapter 19/Spatial Model.w"
int spatial_intervene_in_assertion(parse_node *px, parse_node *py) {
if (Parser__Nodes__int_annotation(py, nowhere_ANNOT)) {
inference_subject *left_subject = Parser__Nodes__get_subject(px);
if (left_subject) {
if (World__Subjects__domain(left_subject))
Problems__subject_problem_at_sentence(_P_(C19KindNowhere),
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_true_about(
Calculus__Propositions__to_put_nowhere(), left_subject, prevailing_mood);
return TRUE;
}
}
return FALSE;
}
#line 511 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__infer_presence_here(instance *I) {
inference_subject *infs = Data__Instances__as_subject(I);
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, infs, PARENTAGE_HERE_INF) {
Problems__contradiction_problem(_P_(C19DuplicateHere),
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,
Parser__Assertions__get_current_subject(), NULL);
World__Inferences__draw(IS_ROOM_INF, infs, IMPOSSIBLE_CE, NULL, NULL);
}
#line 532 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__infer_presence_nowhere(instance *I) {
World__Inferences__draw(PARENTAGE_NOWHERE_INF,
Data__Instances__as_subject(I), CERTAIN_CE, NULL, NULL);
World__Inferences__draw(IS_ROOM_INF, Data__Instances__as_subject(I), IMPOSSIBLE_CE,
NULL, NULL);
}
#line 544 "inform7/Chapter 19/Spatial Model.w"
int IF_complete_model(int stage) {
switch(stage) {
case 1: spatial_stage_I(); break;
case 2: spatial_stage_II(); break;
case 3: spatial_stage_III(); break;
case 4: spatial_stage_IV(); break;
}
return FALSE;
}
#line 563 "inform7/Chapter 19/Spatial Model.w"
int spatial_stage_I(void) {
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
{
#line 595 "inform7/Chapter 19/Spatial Model.w"
current_sentence = Data__Instances__get_creating_sentence(I);
kind *designers_choice = NULL;
{
#line 618 "inform7/Chapter 19/Spatial Model.w"
kind *f = NULL;
inference_subject *infs;
for (infs = Kinds__as_subject(Data__Instances__kind(I));
infs; infs = World__Subjects__narrowest_broader_subject(infs)) {
kind *K = World__Subjects__as_kind(infs);
if (Kinds__lt(K, K_object)) {
f = K;
if ((Kinds__eq(f, K_container)) ||
(Kinds__eq(f, K_supporter)) ||
(Kinds__eq(f, K_door)) ||
(Kinds__eq(f, K_person)))
designers_choice = f;
}
}
if (designers_choice == NULL) designers_choice = f;
}
#line 598 "inform7/Chapter 19/Spatial Model.w"
;
kind *geography_choice = NULL;
inference *geography_inference = NULL;
int geography_certainty = UNKNOWN_CE;
{
#line 639 "inform7/Chapter 19/Spatial Model.w"
inference *inf;
KNOWLEDGE_LOOP(inf, Data__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, Data__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 603 "inform7/Chapter 19/Spatial Model.w"
;
if ((geography_choice) &&
(Kinds__eq(geography_choice, designers_choice) == FALSE))
{
#line 662 "inform7/Chapter 19/Spatial Model.w"
parse_node *sentence_setting_kind = Data__Instances__get_kind_set_sentence(I);
if ((designers_choice == NULL) ||
((geography_certainty == CERTAIN_CE) &&
(Kinds__le(geography_choice, designers_choice))))
{
#line 675 "inform7/Chapter 19/Spatial Model.w"
LOGIF(KIND_CHANGES, "Accepting geography choice of kind of $O as $u\n",
I, geography_choice);
Calculus__Propositions__assert_kind_of_object(I, geography_choice);
}
#line 666 "inform7/Chapter 19/Spatial Model.w"
else if ((geography_certainty == CERTAIN_CE) &&
(!((Kinds__eq(designers_choice, K_door)) &&
(Kinds__eq(geography_choice, K_room)))))
{
#line 682 "inform7/Chapter 19/Spatial Model.w"
LOG("Choices: designer $u, geography $u.\n", designers_choice, geography_choice);
parse_node *decider = Data__Instances__get_creating_sentence(I);
if (sentence_setting_kind) decider = sentence_setting_kind;
if (Kinds__eq(designers_choice, K_person))
{
#line 696 "inform7/Chapter 19/Spatial Model.w"
Problems__contradiction_problem(_P_(C19PersonContaining),
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 686 "inform7/Chapter 19/Spatial Model.w"
else if ((Kinds__eq(designers_choice, K_supporter)) &&
(Kinds__eq(geography_choice, K_container)))
{
#line 708 "inform7/Chapter 19/Spatial Model.w"
Problems__contradiction_problem(_P_(C19CantContainAndSupport),
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 689 "inform7/Chapter 19/Spatial Model.w"
else
{
#line 720 "inform7/Chapter 19/Spatial Model.w"
Problems__contradiction_problem(_P_(C19BothRoomAndSupporter),
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 691 "inform7/Chapter 19/Spatial Model.w"
;
}
#line 670 "inform7/Chapter 19/Spatial Model.w"
;
}
#line 607 "inform7/Chapter 19/Spatial Model.w"
;
if (Kinds__eq(Data__Instances__kind(I), K_object))
Calculus__Propositions__assert_kind_of_object(I, K_thing);
}
#line 566 "inform7/Chapter 19/Spatial Model.w"
;
return FALSE;
}
#line 738 "inform7/Chapter 19/Spatial Model.w"
instance *Plugins__Spatial__progenitor(instance *I) {
if (I == NULL) return NULL;
if (Config__Plugins__plugged_in(spatial_plugin) == FALSE) return NULL;
return PF_I(spatial, I)->progenitor;
}
void Plugins__Spatial__set_progenitor(instance *of, instance *to, inference *reason) {
if (Config__Plugins__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 756 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__void_progenitor(instance *of) {
if (Config__Plugins__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 769 "inform7/Chapter 19/Spatial Model.w"
int spatial_stage_II(void) {
{
#line 785 "inform7/Chapter 19/Spatial Model.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
PF_I(spatial, I)->here_flag = FALSE;
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), PARENTAGE_HERE_INF)
PF_I(spatial, I)->here_flag = TRUE;
}
}
#line 770 "inform7/Chapter 19/Spatial Model.w"
;
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PF_I(spatial, I)->here_flag == FALSE)
{
#line 822 "inform7/Chapter 19/Spatial Model.w"
inference *parent_setting_inference = NULL;
{
#line 838 "inform7/Chapter 19/Spatial Model.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), PARENTAGE_NOWHERE_INF)
{
#line 849 "inform7/Chapter 19/Spatial Model.w"
if (parent_setting_inference) {
Problems__contradiction_problem(_P_(C19DuplicateParentage),
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 840 "inform7/Chapter 19/Spatial Model.w"
;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), PARENTAGE_HERE_INF)
{
#line 849 "inform7/Chapter 19/Spatial Model.w"
if (parent_setting_inference) {
Problems__contradiction_problem(_P_(C19DuplicateParentage),
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 842 "inform7/Chapter 19/Spatial Model.w"
;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), PARENTAGE_INF)
{
#line 849 "inform7/Chapter 19/Spatial Model.w"
if (parent_setting_inference) {
Problems__contradiction_problem(_P_(C19DuplicateParentage),
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 844 "inform7/Chapter 19/Spatial Model.w"
;
}
#line 823 "inform7/Chapter 19/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 862 "inform7/Chapter 19/Spatial Model.w"
if (Plugins__Spatial__object_is_a_room(whereabouts) == FALSE) whereabouts = NULL;
if (whereabouts == NULL) {
parse_node *here_sentence =
World__Inferences__where_inferred(parent_setting_inference);
{
#line 882 "inform7/Chapter 19/Spatial Model.w"
parse_node *sent;
TREE_LOOP(sent) {
if (sent == here_sentence) break;
inference_subject *isub = Parser__Nodes__get_interpretation_of_subject(sent);
instance *sub = World__Subjects__as_instance(isub);
if (Plugins__Spatial__object_is_a_room(sub)) whereabouts = sub;
}
}
#line 866 "inform7/Chapter 19/Spatial Model.w"
;
if (whereabouts == NULL) {
current_sentence = here_sentence;
Problems__object_problem_at_sentence(_P_(C19NoHere),
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 827 "inform7/Chapter 19/Spatial Model.w"
;
if (whereabouts) {
Plugins__Spatial__set_progenitor(I, whereabouts, parent_setting_inference);
LOGIF(OBJECT_TREE, "Progenitor of $O is $O\n", I, whereabouts);
}
}
{
#line 893 "inform7/Chapter 19/Spatial Model.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), PART_OF_INF) {
if ((Plugins__Spatial__object_is_a_room(I)) || (Plugins__Map__object_is_a_door(I))) {
Problems__object_problem(_P_(C19RoomOrDoorAsPart),
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 833 "inform7/Chapter 19/Spatial Model.w"
;
}
#line 774 "inform7/Chapter 19/Spatial Model.w"
;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PF_I(spatial, I)->here_flag)
{
#line 822 "inform7/Chapter 19/Spatial Model.w"
inference *parent_setting_inference = NULL;
{
#line 838 "inform7/Chapter 19/Spatial Model.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), PARENTAGE_NOWHERE_INF)
{
#line 849 "inform7/Chapter 19/Spatial Model.w"
if (parent_setting_inference) {
Problems__contradiction_problem(_P_(C19DuplicateParentage),
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 840 "inform7/Chapter 19/Spatial Model.w"
;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), PARENTAGE_HERE_INF)
{
#line 849 "inform7/Chapter 19/Spatial Model.w"
if (parent_setting_inference) {
Problems__contradiction_problem(_P_(C19DuplicateParentage),
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 842 "inform7/Chapter 19/Spatial Model.w"
;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), PARENTAGE_INF)
{
#line 849 "inform7/Chapter 19/Spatial Model.w"
if (parent_setting_inference) {
Problems__contradiction_problem(_P_(C19DuplicateParentage),
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 844 "inform7/Chapter 19/Spatial Model.w"
;
}
#line 823 "inform7/Chapter 19/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 862 "inform7/Chapter 19/Spatial Model.w"
if (Plugins__Spatial__object_is_a_room(whereabouts) == FALSE) whereabouts = NULL;
if (whereabouts == NULL) {
parse_node *here_sentence =
World__Inferences__where_inferred(parent_setting_inference);
{
#line 882 "inform7/Chapter 19/Spatial Model.w"
parse_node *sent;
TREE_LOOP(sent) {
if (sent == here_sentence) break;
inference_subject *isub = Parser__Nodes__get_interpretation_of_subject(sent);
instance *sub = World__Subjects__as_instance(isub);
if (Plugins__Spatial__object_is_a_room(sub)) whereabouts = sub;
}
}
#line 866 "inform7/Chapter 19/Spatial Model.w"
;
if (whereabouts == NULL) {
current_sentence = here_sentence;
Problems__object_problem_at_sentence(_P_(C19NoHere),
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 827 "inform7/Chapter 19/Spatial Model.w"
;
if (whereabouts) {
Plugins__Spatial__set_progenitor(I, whereabouts, parent_setting_inference);
LOGIF(OBJECT_TREE, "Progenitor of $O is $O\n", I, whereabouts);
}
}
{
#line 893 "inform7/Chapter 19/Spatial Model.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), PART_OF_INF) {
if ((Plugins__Spatial__object_is_a_room(I)) || (Plugins__Map__object_is_a_door(I))) {
Problems__object_problem(_P_(C19RoomOrDoorAsPart),
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 833 "inform7/Chapter 19/Spatial Model.w"
;
}
#line 777 "inform7/Chapter 19/Spatial Model.w"
;
{
#line 796 "inform7/Chapter 19/Spatial Model.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
if ((Plugins__Spatial__progenitor(I)) &&
(Data__Instances__of_kind(I, K_thing) == FALSE) &&
(Data__Instances__of_kind(I, K_room) == FALSE) &&
(Plugins__Regions__object_is_a_region(I) == FALSE)) {
Problems__quote_source(1, Data__Instances__get_creating_sentence(I));
Problems__quote_object(2, I);
Problems__quote_object(3, Plugins__Spatial__progenitor(I));
Problems__quote_kind(4, Data__Instances__kind(I));
Problems__handmade_problem(_P_(C19NonThingInModel));
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 778 "inform7/Chapter 19/Spatial Model.w"
;
return FALSE;
}
#line 930 "inform7/Chapter 19/Spatial Model.w"
void log_object_tree(void) {
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PF_I(spatial, I)->object_tree_parent == NULL)
log_object_tree_recursively(I, 0);
}
void 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)
log_object_tree_recursively(PF_I(spatial, I)->object_tree_child, depth+1);
if (PF_I(spatial, I)->object_tree_sibling)
log_object_tree_recursively(PF_I(spatial, I)->object_tree_sibling, depth);
}
#line 955 "inform7/Chapter 19/Spatial Model.w"
void 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 983 "inform7/Chapter 19/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 961 "inform7/Chapter 19/Spatial Model.w"
;
{
#line 1001 "inform7/Chapter 19/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 962 "inform7/Chapter 19/Spatial Model.w"
;
}
#line 969 "inform7/Chapter 19/Spatial Model.w"
void 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 983 "inform7/Chapter 19/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 19/Spatial Model.w"
;
{
#line 1014 "inform7/Chapter 19/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 977 "inform7/Chapter 19/Spatial Model.w"
;
}
#line 1028 "inform7/Chapter 19/Spatial Model.w"
int Plugins__Spatial__encloses(instance *I1, instance *I2) {
while (I1) {
I1 = Plugins__Spatial__progenitor(I1);
if (I1 == I2) return TRUE;
}
return FALSE;
}
#line 1041 "inform7/Chapter 19/Spatial Model.w"
int spatial_stage_III(void) {
int well_founded = TRUE;
{
#line 1058 "inform7/Chapter 19/Spatial Model.w"
instance *I;
int max_loop = NUMBER_CREATED(instance) + 1;
LOOP_OVER_OBJECT_INSTANCES(I) {
instance *I2;
int k;
for (I2 = Plugins__Spatial__progenitor(I), k=0;
(I2) && (k<max_loop);
I2 = Plugins__Spatial__progenitor(I2), k++) {
if (I2 == I) {
{
#line 1077 "inform7/Chapter 19/Spatial Model.w"
Problems__quote_object(1, I);
Problems__handmade_problem(_P_(C19IllFounded));
Problems__issue_problem_segment("The %1 seems to be containing itself: ");
instance *I3 = I;
while (TRUE) {
int w1, w2;
Data__Instances__get_name(I3, &w1, &w2, FALSE);
parse_node *creator = Parser__Sentences__NPs__new_raw(w1, w2);
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 = Plugins__Spatial__progenitor(I3);
if (I3 == I) break;
}
Problems__issue_problem_segment("%1... and so on. This is forbidden.");
Problems__issue_problem_end();
}
#line 1067 "inform7/Chapter 19/Spatial Model.w"
;
Plugins__Spatial__void_progenitor(I); /* thus cutting the cycle */
well_founded = FALSE;
}
}
}
}
#line 1043 "inform7/Chapter 19/Spatial Model.w"
;
if (well_founded)
{
#line 1114 "inform7/Chapter 19/Spatial Model.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
if (Plugins__Spatial__progenitor(I))
adopt_object(I, Plugins__Spatial__progenitor(I));
if (PF_I(spatial, I)->part_flag)
part_object(I);
}
}
#line 1044 "inform7/Chapter 19/Spatial Model.w"
;
{
#line 1128 "inform7/Chapter 19/Spatial Model.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
int portable = FALSE;
instance *J = I;
for (J = Plugins__Spatial__progenitor(I); J; J = Plugins__Spatial__progenitor(J)) {
if (PF_I(spatial, J)->part_flag) break;
if (Data__Instances__of_kind(J, K_person)) {
portable = TRUE;
break;
}
}
if (portable)
Properties__EitherOr__assert(
P_fixed_in_place, Data__Instances__as_subject(I), FALSE, CERTAIN_CE);
}
}
#line 1045 "inform7/Chapter 19/Spatial Model.w"
;
{
#line 1147 "inform7/Chapter 19/Spatial Model.w"
{
#line 1158 "inform7/Chapter 19/Spatial Model.w"
if (K_room) {
inference *inf;
int desc_seen = FALSE;
POSITIVE_KNOWLEDGE_LOOP(inf, Kinds__as_subject(K_room), PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_description)
desc_seen = TRUE;
if (desc_seen == FALSE) {
STREAM *val = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(val) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for name text");
STREAM_WRITE(val, "\"\"");
Properties__Valued__assert(P_description, Kinds__as_subject(K_room),
Specifications__Values__new_text_literal_from_stream(val), LIKELY_CE);
}
}
}
#line 1147 "inform7/Chapter 19/Spatial Model.w"
;
{
#line 1180 "inform7/Chapter 19/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 (Data__Instances__of_kind(I, K_room))
Properties__EitherOr__assert(
P_mark_as_room, Data__Instances__as_subject(I), TRUE, CERTAIN_CE);
if (Data__Instances__of_kind(I, K_thing))
Properties__EitherOr__assert(
P_mark_as_thing, Data__Instances__as_subject(I), TRUE, CERTAIN_CE);
}
}
#line 1148 "inform7/Chapter 19/Spatial Model.w"
;
{
#line 1197 "inform7/Chapter 19/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) {
specification *nothing_constant = Specifications__Values__new_nothing_object_constant();
Properties__Valued__assert(P_component_parent, Kinds__as_subject(K_thing),
nothing_constant, CERTAIN_CE);
Properties__Valued__assert(P_component_child, Kinds__as_subject(K_thing),
nothing_constant, CERTAIN_CE);
Properties__Valued__assert(P_component_sibling, Kinds__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, Data__Instances__as_subject(I),
Data__Instances__get_value(cp), CERTAIN_CE);
instance *cc = PF_I(spatial, I)->incorp_tree_child;
if (cc) Properties__Valued__assert(P_component_child, Data__Instances__as_subject(I),
Data__Instances__get_value(cc), CERTAIN_CE);
instance *cs = PF_I(spatial, I)->incorp_tree_sibling;
if (cs) Properties__Valued__assert(P_component_sibling, Data__Instances__as_subject(I),
Data__Instances__get_value(cs), CERTAIN_CE);
}
}
#line 1149 "inform7/Chapter 19/Spatial Model.w"
;
}
#line 1046 "inform7/Chapter 19/Spatial Model.w"
;
{
#line 1233 "inform7/Chapter 19/Spatial Model.w"
Properties__Implementation__OfObjects__begin_sequencing_objects();
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PF_I(spatial, I)->object_tree_parent == NULL)
add_to_object_sequence(I, 0);
}
#line 1047 "inform7/Chapter 19/Spatial Model.w"
;
if (Log__Aspects__on(OBJECT_TREE_DA)) log_object_tree();
return FALSE;
}
#line 1242 "inform7/Chapter 19/Spatial Model.w"
void add_to_object_sequence(instance *I, int depth) {
Properties__Implementation__OfObjects__place_this_object_next(I);
PF_I(spatial, I)->I6_definition_depth = depth;
if (PF_I(spatial, I)->object_tree_child)
add_to_object_sequence(PF_I(spatial, I)->object_tree_child, depth+1);
if (PF_I(spatial, I)->object_tree_sibling)
add_to_object_sequence(PF_I(spatial, I)->object_tree_sibling, depth);
}
#line 1256 "inform7/Chapter 19/Spatial Model.w"
int Plugins__Spatial__get_definition_depth(instance *I) {
if (Config__Plugins__plugged_in(spatial_plugin))
return PF_I(spatial, I)->I6_definition_depth;
return 0;
}
#line 1268 "inform7/Chapter 19/Spatial Model.w"
int spatial_stage_IV(void) {
if (existing_story_file) {
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (Plugins__Spatial__object_is_a_room(I)) {
Problems__unlocated_problem(_P_(C19RoomInIgnoredSource),
"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 1289 "inform7/Chapter 19/Spatial Model.w"
void Plugins__Spatial__index_spatial_relationship(instance *I) {
char *rel = NULL;
instance *P = Plugins__Spatial__progenitor(I);
if (P) {
/* we could set |rel| to "in" here, but the index omits that for clarity */
if (Data__Instances__of_kind(P, K_supporter)) rel = "on";
if (Data__Instances__of_kind(P, K_person)) rel = "carried";
if (PF_I(spatial, I)->part_flag) rel = "part";
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_worn)
rel = "worn";
}
if (rel) INDEX("<i>%s</i> ", rel);
}
#line 1309 "inform7/Chapter 19/Spatial Model.w"
int Plugins__Spatial__no_detail_index(instance *I) {
if (PF_I(spatial, I)->incorp_tree_parent != NULL) return TRUE;
return FALSE;
}
#line 1317 "inform7/Chapter 19/Spatial Model.w"
void Plugins__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 ((Plugins__Spatial__object_is_a_room(I)) &&
(Plugins__Map__object_is_a_door(I) == FALSE)) {
instance *I2;
LOOP_OVER_OBJECT_INSTANCES(I2) {
if ((Plugins__Map__object_is_a_door(I2)) && (Plugins__Spatial__progenitor(I2) != I)) {
instance *A = NULL, *B = NULL;
Plugins__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);
}
}
}
Plugins__Player__index_object_further(I, depth, details);
Plugins__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 1350 "inform7/Chapter 19/Spatial Model.w"
int spatial_add_to_World_index(instance *O) {
if ((O) && (Data__Instances__of_kind(O, K_thing))) {
Formats__HTML__open_para(ifl, 1, "tight");
instance *P = Plugins__Spatial__progenitor(O);
if (P) {
INDEX("<i>initial location:</i> ");
char *rel = "in";
if (Data__Instances__of_kind(P, K_supporter)) rel = "on";
if (Data__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, Data__Instances__as_subject(O), PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_worn)
rel = "worn by";
INDEX("%s ", rel);
Data__Instances__index_name(P);
parse_node *at = PF_I(spatial, O)->progenitor_set_at;
if (at) Index__link(at->word_ref1);
}
INDEX("</p>");
}
return FALSE;
}
#line 33 "inform7/Chapter 19/Spatial Relations.w"
void Plugins__Spatial__Relations__create_initial_stock(void) {
{
#line 50 "inform7/Chapter 19/Spatial Relations.w"
R_containment =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__full_new(NULL, NULL, -1, -1, Code__Schemas__new("ContainerOf(*1)")),
Semantics__BPs__Terms__new(NULL),
"contains", "is-in",
NULL, Code__Schemas__new("MoveObject(*2,*1)"), NULL,
Text__Languages__wording(relation_names_NTM, CONTAINMENT_RELATION_NAME));
R_containment->loop_parent_optimisation_proviso = "ContainerOf";
R_containment->loop_parent_optimisation_ranger = "TestContainmentRange";
Semantics__BPs__set_index_details(R_containment, "container/room", "thing");
R_support =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__full_new(infs_supporter, NULL, -1, -1, Code__Schemas__new("SupporterOf(*1)")),
Semantics__BPs__Terms__new(infs_thing),
"supports", "is-on",
NULL, Code__Schemas__new("MoveObject(*2,*1)"), NULL,
Text__Languages__wording(relation_names_NTM, SUPPORT_RELATION_NAME));
R_support->loop_parent_optimisation_proviso = "SupporterOf";
R_incorporation =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__full_new(infs_thing, NULL, -1, -1, Code__Schemas__new("(*1.component_parent)")),
Semantics__BPs__Terms__new(infs_thing),
"incorporates", "is-part-of",
NULL, Code__Schemas__new("MakePart(*2,*1)"), NULL,
Text__Languages__wording(relation_names_NTM, INCORPORATION_RELATION_NAME));
R_carrying =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__full_new(infs_person, NULL, -1, -1, Code__Schemas__new("CarrierOf(*1)")),
Semantics__BPs__Terms__new(infs_thing),
"carries", "is-carried-by",
NULL, Code__Schemas__new("MoveObject(*2,*1)"), NULL,
Text__Languages__wording(relation_names_NTM, CARRYING_RELATION_NAME));
R_carrying->loop_parent_optimisation_proviso = "CarrierOf";
R_holding =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__full_new(infs_person, NULL, -1, -1, Code__Schemas__new("HolderOf(*1)")),
Semantics__BPs__Terms__new(infs_thing),
"holds", "is-held-by",
NULL, Code__Schemas__new("MoveObject(*2,*1)"), NULL,
Text__Languages__wording(relation_names_NTM, HOLDING_RELATION_NAME));
/* can't be optimised, because parts are also held */
R_wearing =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__full_new(infs_person, NULL, -1, -1, Code__Schemas__new("WearerOf(*1)")),
Semantics__BPs__Terms__new(infs_thing),
"wears", "is-worn-by",
NULL, Code__Schemas__new("WearObject(*2,*1)"), NULL,
Text__Languages__wording(relation_names_NTM, WEARING_RELATION_NAME));
R_wearing->loop_parent_optimisation_proviso = "WearerOf";
a_has_b_predicate =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__full_new(NULL, NULL, -1, -1, Code__Schemas__new("OwnerOf(*1)")),
Semantics__BPs__Terms__new(NULL),
"has", "is-had-by",
NULL, Code__Schemas__new("MoveObject(*2,*1)"), NULL,
Text__Languages__wording(relation_names_NTM, POSSESSION_RELATION_NAME));
a_has_b_predicate->loop_parent_optimisation_proviso = "OwnerOf";
Semantics__BPs__set_index_details(a_has_b_predicate, "person", "thing");
room_containment_predicate =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__full_new(infs_room, NULL, -1, -1, Code__Schemas__new("LocationOf(*1)")),
Semantics__BPs__Terms__new(infs_thing),
"is-room-of", "is-in-room",
NULL, Code__Schemas__new("MoveObject(*2,*1)"), NULL,
Text__Languages__wording(relation_names_NTM, ROOM_CONTAINMENT_RELATION_NAME));
room_containment_predicate->loop_parent_optimisation_proviso = "LocationOf";
}
#line 34 "inform7/Chapter 19/Spatial Relations.w"
;
{
#line 121 "inform7/Chapter 19/Spatial Relations.w"
R_visibility =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__new(infs_thing),
Semantics__BPs__Terms__new(infs_thing),
"can-see", "can-be-seen-by",
NULL, NULL, Code__Schemas__new("TestVisibility(*1,*2)"),
Text__Languages__wording(relation_names_NTM, VISIBILITY_RELATION_NAME));
R_touchability =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__new(infs_thing),
Semantics__BPs__Terms__new(infs_thing),
"can-touch", "can-be-touched-by",
NULL, NULL, Code__Schemas__new("TestTouchability(*1,*2)"),
Text__Languages__wording(relation_names_NTM, TOUCHABILITY_RELATION_NAME));
R_concealment =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__new(infs_thing),
Semantics__BPs__Terms__new(infs_thing),
"conceals", "is-concealed-by",
NULL, NULL, Code__Schemas__new("TestConcealment(*1,*2)"),
Text__Languages__wording(relation_names_NTM, CONCEALMENT_RELATION_NAME));
R_enclosure =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__new(Kinds__as_subject(K_object)),
Semantics__BPs__Terms__new(Kinds__as_subject(K_object)),
"encloses", "is-enclosed-by",
NULL, NULL, Code__Schemas__new("IndirectlyContains(*1,*2)"),
Text__Languages__wording(relation_names_NTM, ENCLOSURE_RELATION_NAME));
}
#line 35 "inform7/Chapter 19/Spatial Relations.w"
;
Plugins__Map__create_relations();
Plugins__Regions__create_relations();
}
#line 154 "inform7/Chapter 19/Spatial Relations.w"
void Plugins__Spatial__Relations__create_second_stock(void) {
}
#line 161 "inform7/Chapter 19/Spatial Relations.w"
int Plugins__Spatial__Relations__typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
return DECLINE_TO_MATCH;
}
#line 173 "inform7/Chapter 19/Spatial Relations.w"
int Plugins__Spatial__Relations__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
instance *I0 = World__Subjects__as_instance(infs0),
*I1 = World__Subjects__as_instance(infs1);
if ((I0) && (I1)) {
if (I1 == I0) {
Problems__sentence_problem(_P_(C19MiseEnAbyme),
"this asks to put something inside itself",
"like saying 'the bottle is in the bottle'.");
return TRUE;
}
{
#line 206 "inform7/Chapter 19/Spatial Relations.w"
if (Plugins__Backdrops__assert_relations(bp, I0, I1)) return TRUE;
if (Plugins__Map__assert_relations(bp, I0, I1)) return TRUE;
if (Plugins__Regions__assert_relations(bp, I0, I1)) return TRUE;
}
#line 185 "inform7/Chapter 19/Spatial Relations.w"
;
if (Semantics__BPs__can_be_made_true_at_runtime(bp) == FALSE)
{
#line 213 "inform7/Chapter 19/Spatial Relations.w"
Problems__sentence_problem(_P_(C19Unassertable),
"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 19/Spatial Relations.w"
;
if ((bp == R_incorporation) && (Data__Instances__of_kind(I0, K_room)))
{
#line 224 "inform7/Chapter 19/Spatial Relations.w"
Problems__sentence_problem(_P_(C19PartOfRoom),
"this asks to make something a part of a room",
"when only things are allowed to have parts.");
return TRUE;
}
#line 190 "inform7/Chapter 19/Spatial Relations.w"
;
{
#line 232 "inform7/Chapter 19/Spatial Relations.w"
inference_subject *item = Data__Instances__as_subject(I1);
inference_subject *loc = Data__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 19/Spatial Relations.w"
;
if (bp == R_wearing)
{
#line 248 "inform7/Chapter 19/Spatial Relations.w"
inference_subject *item = Data__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 19/Spatial Relations.w"
;
return TRUE;
}
return FALSE;
}
#line 258 "inform7/Chapter 19/Spatial Relations.w"
int Plugins__Spatial__Relations__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) {
return FALSE;
}
#line 265 "inform7/Chapter 19/Spatial Relations.w"
int Plugins__Spatial__Relations__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 35 "inform7/Chapter 19/The Player.w"
void Plugins__Player__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_VARIABLE_NOTIFY, player_new_quantity_notify);
PLUGIN_REGISTER(PLUGIN_VARIABLE_SET_WARNING, player_variable_set_warning);
PLUGIN_REGISTER(PLUGIN_NEW_INSTANCE_NOTIFY, player_new_instance_notify);
PLUGIN_REGISTER(PLUGIN_IRREGULAR_GENITIVE, player_irregular_genitive);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, player_complete_model);
PLUGIN_REGISTER(PLUGIN_REFINE_IMPLICIT_NOUN, player_refine_implicit_noun);
PLUGIN_REGISTER(PLUGIN_DETECT_BODYSNATCHING, player_detect_bodysnatching);
PLUGIN_REGISTER(PLUGIN_ANNOTATE_IN_WORLD_INDEX, player_annotate_in_World_index);
}
#line 52 "inform7/Chapter 19/The Player.w"
int notable_player_instances_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 54 "inform7/Chapter 19/The Player.w"
#line 58 "inform7/Chapter 19/The Player.w"
int player_new_instance_notify(instance *inst) {
int w1, w2;
Data__Instances__get_name(inst, &w1, &w2, FALSE);
if (parse_nt_against_word_range(notable_player_instances_NTM, w1, w2, NULL, NULL)) {
I_yourself = inst; player_character_object = I_yourself;
if (player_VAR)
{
#line 148 "inform7/Chapter 19/The Player.w"
inference_subject *subj = Data__Instances__as_subject(I_yourself);
World__Subjects__alias_to_nonlocal_variable(subj, player_VAR);
Data__NonlocalVariables__set_alias(player_VAR, subj);
}
#line 63 "inform7/Chapter 19/The Player.w"
;
}
return FALSE;
}
instance *Plugins__Player__get_start_room(void) {
return start_room;
}
#line 93 "inform7/Chapter 19/The Player.w"
int notable_player_variables_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 97 "inform7/Chapter 19/The Player.w"
#line 101 "inform7/Chapter 19/The Player.w"
int player_new_quantity_notify(nonlocal_variable *nlv) {
if (parse_nt_against_word_range(notable_player_variables_NTM, nlv->word_ref1, nlv->word_ref2, NULL, NULL)) {
switch (most_recent_result) {
case 0:
player_VAR = nlv;
if (I_yourself)
{
#line 148 "inform7/Chapter 19/The Player.w"
inference_subject *subj = Data__Instances__as_subject(I_yourself);
World__Subjects__alias_to_nonlocal_variable(subj, player_VAR);
Data__NonlocalVariables__set_alias(player_VAR, subj);
}
#line 106 "inform7/Chapter 19/The Player.w"
;
Data__NonlocalVariables__set_write_schema(nlv, "ChangePlayer(*2)");
break;
case 1:
score_VAR = nlv;
Data__NonlocalVariables__make_initalisable(score_VAR);
break;
case 2:
time_of_day_VAR = nlv;
Data__NonlocalVariables__make_initalisable(time_of_day_VAR);
break;
}
}
return FALSE;
}
#line 160 "inform7/Chapter 19/The Player.w"
int player_variable_set_warning(nonlocal_variable *nlv, specification *val) {
if (nlv == player_VAR) {
instance *npc = Specifications__Values__instance_of_CONSTANT_object_if_any(val);
if (npc) {
player_character_object = npc;
return TRUE;
}
}
return FALSE;
}
#line 194 "inform7/Chapter 19/The Player.w"
int 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 = Data__Instances__kind(player_character_object);
kind *KY = Data__Instances__kind(I_yourself);
if (Kinds__lt(KP, KY)) {
if (body == Data__Instances__as_subject(player_character_object)) {
*snatcher = FALSE; *counterpart = Data__Instances__as_subject(I_yourself); return TRUE; }
if (body == Data__Instances__as_subject(I_yourself)) {
*snatcher = TRUE; *counterpart = Data__Instances__as_subject(player_character_object); return TRUE; }
} else {
if (body == Data__Instances__as_subject(player_character_object)) {
*snatcher = TRUE; *counterpart = Data__Instances__as_subject(I_yourself); return TRUE; }
if (body == Data__Instances__as_subject(I_yourself)) {
*snatcher = FALSE; *counterpart = Data__Instances__as_subject(player_character_object); return TRUE; }
}
return FALSE;
}
#line 222 "inform7/Chapter 19/The Player.w"
int player_irregular_genitive(inference_subject *owner, char *genitive, int *propriety) {
if (owner == Data__Instances__as_subject(I_yourself)) {
strcpy(genitive, "your ");
*propriety = TRUE;
return TRUE;
}
if ((player_character_object) && (I_yourself) &&
(player_character_object != I_yourself) &&
(owner == Data__Instances__as_subject(player_character_object))) {
strcpy(genitive, "your ");
*propriety = TRUE;
return TRUE;
}
return FALSE;
}
#line 246 "inform7/Chapter 19/The Player.w"
int implicit_player_relationship_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 250 "inform7/Chapter 19/The Player.w"
#line 254 "inform7/Chapter 19/The Player.w"
int player_refine_implicit_noun(parse_node *p) {
if (parse_nt_against_word_range(implicit_player_relationship_NTM, p->word_ref1, p->word_ref2, NULL, NULL)) {
Parser__Nodes__noun_from_infs(p, Data__Instances__as_subject(player_character_object));
return TRUE;
}
return FALSE;
}
#line 272 "inform7/Chapter 19/The Player.w"
int player_complete_model(int stage) {
if (stage == 4) {
{
#line 284 "inform7/Chapter 19/The Player.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Plugins__Spatial__object_is_a_room(I)) && (start_room == NULL)
&& (Data__Instances__get_creating_file(I) == primary_source_file))
start_room = I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Plugins__Spatial__object_is_a_room(I)) && (start_room == NULL))
start_room = I;
start_object = start_room;
}
#line 274 "inform7/Chapter 19/The Player.w"
;
{
#line 297 "inform7/Chapter 19/The Player.w"
if ((start_room == NULL) && (existing_story_file == FALSE)) {
Problems__unlocated_problem(_P_(C19NoStartRoom),
"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 275 "inform7/Chapter 19/The Player.w"
;
{
#line 314 "inform7/Chapter 19/The Player.w"
if (player_character_object) {
start_object = Plugins__Spatial__progenitor(player_character_object);
if (start_object) {
start_room = start_object;
while ((start_room) && (Plugins__Spatial__progenitor(start_room)))
start_room = Plugins__Spatial__progenitor(start_room);
if ((start_room) && (Plugins__Spatial__object_is_a_room(start_room) == FALSE)) {
Problems__object_problem(_P_(C19StartsOutsideRooms),
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,
Data__Instances__as_subject(player_character_object), PART_OF_INF) {
Problems__object_problem(_P_(C19PlayerIsPart),
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 276 "inform7/Chapter 19/The Player.w"
;
}
return FALSE;
}
#line 346 "inform7/Chapter 19/The Player.w"
void Plugins__Player__InitialSituation_array(OUTPUT_STREAM) {
if (Config__Plugins__plugged_in(player_plugin)) {
WRITE("Array InitialSituation --> ");
Data__NonlocalVariables__compile_initial_value(OUT, player_VAR);
WRITE(" %s", Data__Instances__identifier(start_object));
WRITE(" %s ", Data__Instances__identifier(start_room));
Data__NonlocalVariables__compile_initial_value(OUT, time_of_day_VAR);
WRITE(" 0;\n\n");
}
}
#line 362 "inform7/Chapter 19/The Player.w"
void Plugins__Player__index_object_further(instance *I, int depth, int details) {
if ((I == start_room) && (I_yourself) &&
(Data__Instances__indexed_yet(I_yourself) == FALSE))
Data__Objects__index(I_yourself, NULL, depth+1, details);
}
int player_annotate_in_World_index(instance *I) {
if (I == Plugins__Player__get_start_room()) {
INDEX(" - <i>room where play begins</i>");
Index__doc_link("ROOMPLAYBEGINS");
return TRUE;
}
return FALSE;
}
#line 27 "inform7/Chapter 19/Backdrops.w"
void Plugins__Backdrops__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, backdrops_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, backdrops_new_property_notify);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, backdrops_complete_model);
PLUGIN_REGISTER(PLUGIN_LOG_INFERENCE_TYPE, backdrops_log_inference_type);
PLUGIN_REGISTER(PLUGIN_ESTIMATE_PROPERTY_USAGE, backdrops_estimate_property_usage);
PLUGIN_REGISTER(PLUGIN_INTERVENE_IN_ASSERTION, backdrops_intervene_in_assertion);
}
#line 42 "inform7/Chapter 19/Backdrops.w"
int notable_backdrops_kinds_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 44 "inform7/Chapter 19/Backdrops.w"
#line 48 "inform7/Chapter 19/Backdrops.w"
int backdrops_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) {
if (parse_nt_against_word_range(notable_backdrops_kinds_NTM, w1, w2, NULL, NULL)) {
K_backdrop = new_base; return TRUE;
}
return FALSE;
}
#line 58 "inform7/Chapter 19/Backdrops.w"
int object_is_a_backdrop(instance *I) {
if ((Config__Plugins__plugged_in(regions_plugin)) && (K_backdrop) && (I) &&
(Data__Instances__of_kind(I, K_backdrop))) return TRUE;
return FALSE;
}
#line 70 "inform7/Chapter 19/Backdrops.w"
int notable_backdrops_properties_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 72 "inform7/Chapter 19/Backdrops.w"
#line 76 "inform7/Chapter 19/Backdrops.w"
int backdrops_new_property_notify(property *prn) {
if (parse_nt_against_word_range(notable_backdrops_properties_NTM, prn->word_ref1, prn->word_ref2, NULL, NULL))
P_scenery = prn;
return FALSE;
}
int Plugins__Backdrops__object_is_scenery(instance *I) {
if (World__Inferences__get_EO_state(Data__Instances__as_subject(I), P_scenery) > 0)
return TRUE;
return FALSE;
}
#line 91 "inform7/Chapter 19/Backdrops.w"
int backdrops_estimate_property_usage(kind *k, int *words_used) {
if (Kinds__eq(k, K_backdrop)) *words_used += 2;
return FALSE;
}
#line 99 "inform7/Chapter 19/Backdrops.w"
int 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 19/Backdrops.w"
int Plugins__Backdrops__assert_relations(binary_predicate *relation,
instance *I0, instance *I1) {
if ((Data__Instances__of_kind(I1, K_backdrop)) &&
((relation == R_incorporation) ||
(relation == R_containment) ||
(relation == R_regional_containment))) {
inference_subject *bd = Data__Instances__as_subject(I1);
inference_subject *loc = Data__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 19/Backdrops.w"
void Plugins__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 19/Backdrops.w"
int notable_backdrops_noun_phrases_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 180 "inform7/Chapter 19/Backdrops.w"
#line 184 "inform7/Chapter 19/Backdrops.w"
int backdrops_intervene_in_assertion(parse_node *px, parse_node *py) {
if ((Parser__Nodes__type(py) == EVERY_NT) &&
(parse_nt_against_word_range(notable_backdrops_noun_phrases_NTM, py->word_ref1, py->word_ref2, NULL, NULL))) {
inference_subject *left_subject = Parser__Nodes__get_subject(px);
if (left_subject == NULL)
Problems__assertion_problem(_P_(C19ValueEverywhere),
"'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 (World__Subjects__domain(left_subject))
Problems__subject_problem_at_sentence(_P_(C19KindOfBackdropEverywhere),
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_true_about(
Calculus__Propositions__to_put_everywhere(), left_subject, prevailing_mood);
return TRUE;
}
return FALSE;
}
#line 211 "inform7/Chapter 19/Backdrops.w"
void Plugins__Backdrops__infer_presence_everywhere(instance *I) {
if ((I == NULL) || (Data__Instances__of_kind(I, K_backdrop) == FALSE)) {
Problems__sentence_problem(_P_(C19EverywhereNonBackdrop),
"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,
Data__Instances__as_subject(I), prevailing_mood, NULL, NULL);
}
#line 228 "inform7/Chapter 19/Backdrops.w"
int backdrops_complete_model(int stage) {
if (stage == 2) {
P_absent = Properties__EitherOr__new_nameless("absent");
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
STREAM *FOUNDIN = NULL;
{
#line 252 "inform7/Chapter 19/Backdrops.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), FOUND_EVERYWHERE_INF) {
{
#line 313 "inform7/Chapter 19/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 19/Backdrops.w"
;
STREAM_WRITE(FOUNDIN, "FoundEverywhere");
break;
}
}
#line 234 "inform7/Chapter 19/Backdrops.w"
;
int room_count = 0, region_count = 0;
{
#line 262 "inform7/Chapter 19/Backdrops.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), FOUND_IN_INF) {
instance *loc = World__Inferences__get_reference_as_object(inf);
if ((K_region) && (Data__Instances__of_kind(loc, K_region))) region_count++;
else room_count++;
}
}
#line 236 "inform7/Chapter 19/Backdrops.w"
;
if ((FOUNDIN == NULL) && (room_count > 0) && (room_count < 16) && (region_count == 0))
{
#line 272 "inform7/Chapter 19/Backdrops.w"
{
#line 313 "inform7/Chapter 19/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 19/Backdrops.w"
;
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), FOUND_IN_INF)
STREAM_WRITE(FOUNDIN, "%s ",
Data__Instances__identifier(World__Inferences__get_reference_as_object(inf)));
}
#line 238 "inform7/Chapter 19/Backdrops.w"
;
if ((FOUNDIN == NULL) && (room_count + region_count > 0))
{
#line 281 "inform7/Chapter 19/Backdrops.w"
{
#line 313 "inform7/Chapter 19/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 19/Backdrops.w"
;
FOUNDIN = Code__Routines__begin(FOUNDIN, "*");
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), FOUND_IN_INF) {
instance *loc = World__Inferences__get_reference_as_object(inf);
if ((K_region) && (Data__Instances__of_kind(loc, K_region)))
STREAM_WRITE(FOUNDIN, "if (TestRegionalContainment(location, %s)) rtrue; ",
Data__Instances__identifier(loc));
else
STREAM_WRITE(FOUNDIN, "if (location == %s) rtrue; ",
Data__Instances__identifier(loc));
}
FOUNDIN = Code__Routines__end(FOUNDIN);
STREAM_WRITE(FOUNDIN, ",");
}
#line 240 "inform7/Chapter 19/Backdrops.w"
;
if ((FOUNDIN == NULL) && (Data__Instances__of_kind(I, K_backdrop)))
{
#line 302 "inform7/Chapter 19/Backdrops.w"
{
#line 313 "inform7/Chapter 19/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 19/Backdrops.w"
;
FOUNDIN = Code__Routines__begin(FOUNDIN, "*");
STREAM_WRITE(FOUNDIN, "rfalse;");
FOUNDIN = Code__Routines__end(FOUNDIN);
STREAM_WRITE(FOUNDIN, ",");
Properties__EitherOr__assert(
P_absent, Data__Instances__as_subject(I), TRUE, CERTAIN_CE);
}
#line 242 "inform7/Chapter 19/Backdrops.w"
;
if (FOUNDIN) Plugins__Map__set_found_in(I, FOUNDIN);
}
}
return FALSE;
}
#line 43 "inform7/Chapter 19/Regions.w"
void Plugins__Regions__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, regions_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_SET_SUBKIND_NOTIFY, regions_set_subkind_notify);
PLUGIN_REGISTER(PLUGIN_NEW_SUBJECT_NOTIFY, regions_new_subject_notify);
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, regions_new_property_notify);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, regions_complete_model);
PLUGIN_REGISTER(PLUGIN_MORE_SPECIFIC, regions_more_specific);
PLUGIN_REGISTER(PLUGIN_ESTIMATE_PROPERTY_USAGE, regions_estimate_property_usage);
PLUGIN_REGISTER(PLUGIN_INTERVENE_IN_ASSERTION, regions_intervene_in_assertion);
PLUGIN_REGISTER(PLUGIN_NAME_TO_EARLY_INFS, regions_name_to_early_infs);
PLUGIN_REGISTER(PLUGIN_ADD_TO_WORLD_INDEX, regions_add_to_World_index);
infs_region = World__Subjects__new(global_constants,
FUND_SUB, NULL_GENERAL_POINTER, LIKELY_CE);
}
regions_data *regions_plugin_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 19/Regions.w"
int notable_regions_kinds_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 73 "inform7/Chapter 19/Regions.w"
#line 77 "inform7/Chapter 19/Regions.w"
int regions_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) {
if (parse_nt_against_word_range(notable_regions_kinds_NTM, w1, w2, NULL, NULL)) {
K_region = new_base; return TRUE;
}
return FALSE;
}
int regions_new_subject_notify(inference_subject *subj) {
CREATE_PF_DATA(regions, subj);
return FALSE;
}
#line 92 "inform7/Chapter 19/Regions.w"
int regions_set_subkind_notify(kind *sub, kind *super) {
if ((sub == K_region) && (super != K_object)) {
Problems__sentence_problem(_P_(C19RegionAdrift),
"'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 107 "inform7/Chapter 19/Regions.w"
int Plugins__Regions__object_is_a_region(instance *I) {
if ((Config__Plugins__plugged_in(regions_plugin)) && (K_region) && (I) &&
(Data__Instances__of_kind(I, K_region))) return TRUE;
return FALSE;
}
#line 119 "inform7/Chapter 19/Regions.w"
int regions_more_specific(instance *I1, instance *I2) {
int r1 = Data__Instances__of_kind(I1, K_room);
int r2 = Data__Instances__of_kind(I2, K_room);
int reg1 = Data__Instances__of_kind(I1, K_region);
int reg2 = Data__Instances__of_kind(I2, K_region);
if ((r1) && (reg2)) return 1;
if ((reg1) && (r2)) return -1;
if ((reg1) && (reg2)) {
if (Plugins__Spatial__encloses(I1, I2)) return 1;
if (Plugins__Spatial__encloses(I2, I1)) return -1;
}
return 0;
}
#line 139 "inform7/Chapter 19/Regions.w"
int notable_regions_properties_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 141 "inform7/Chapter 19/Regions.w"
#line 145 "inform7/Chapter 19/Regions.w"
int regions_new_property_notify(property *prn) {
if (parse_nt_against_word_range(notable_regions_properties_NTM, prn->word_ref1, prn->word_ref2, NULL, NULL))
P_map_region = prn;
return FALSE;
}
#line 154 "inform7/Chapter 19/Regions.w"
int regions_estimate_property_usage(kind *k, int *words_used) {
if (Kinds__eq(k, K_region)) *words_used += 2;
return FALSE;
}
#line 164 "inform7/Chapter 19/Regions.w"
int regions_intervene_in_assertion(parse_node *px, parse_node *py) {
if ((Parser__Nodes__type(px) == PROPER_NOUN_NT) &&
(Parser__Nodes__type(py) == COMMON_NOUN_NT)) {
inference_subject *left_subject = Parser__Nodes__get_subject(px);
inference_subject *right_kind = Parser__Nodes__get_subject(py);
if ((World__Subjects__is_an_object(left_subject)) &&
(right_kind == Kinds__as_subject(K_region))) {
instance *left_object = World__Subjects__as_instance(left_subject);
if ((left_object) &&
(current_sentence != Data__Instances__get_creating_sentence(left_object)) &&
(Data__Instances__of_kind(left_object, K_region) == FALSE)) {
Problems__subject_problem_at_sentence(_P_(C19ExistingRegion),
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 ((Parser__Nodes__type(px) == RELATIONSHIP_NT) &&
(Parser__Nodes__get_subject(py) == Kinds__as_subject(K_region))) {
Problems__assertion_problem(_P_(C19RegionRelated),
"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 205 "inform7/Chapter 19/Regions.w"
int regions_name_to_early_infs(int w1, int w2, inference_subject **infs) {
if ((parse_nt_against_word_range(notable_regions_kinds_NTM, w1, w2, NULL, NULL)) && (K_region == NULL)) *infs = infs_region;
return FALSE;
}
#line 213 "inform7/Chapter 19/Regions.w"
void Plugins__Regions__create_relations(void) {
R_regional_containment =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__new(infs_region),
Semantics__BPs__Terms__new(Kinds__as_subject(K_object)),
"region-contains", "in-region",
NULL, NULL, Code__Schemas__new("TestRegionalContainment(*2,*1)"),
Text__Languages__wording(relation_names_NTM,
REGIONAL_CONTAINMENT_RELATION_NAME));
Semantics__BPs__set_index_details(R_regional_containment, NULL, "room/region");
}
#line 231 "inform7/Chapter 19/Regions.w"
int Plugins__Regions__assert_relations(binary_predicate *relation,
instance *I0, instance *I1) {
int I0_is_region = FALSE;
if (Data__Instances__of_kind(I0, K_region)) I0_is_region = TRUE;
int I1_is_region = FALSE;
if (Data__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 259 "inform7/Chapter 19/Regions.w"
if ((PF_I(regions, I1)->in_region) &&
(PF_I(regions, I1)->in_region != I0)) {
Problems__sentence_problem(_P_(C19RegionInTwoRegions),
"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 242 "inform7/Chapter 19/Regions.w"
;
if (I1_is_region)
{
#line 274 "inform7/Chapter 19/Regions.w"
inference_subject *inner = Data__Instances__as_subject(I1);
inference_subject *outer = Data__Instances__as_subject(I0);
World__Inferences__draw(PARENTAGE_INF, inner, CERTAIN_CE, outer, NULL);
}
#line 243 "inform7/Chapter 19/Regions.w"
else
{
#line 282 "inform7/Chapter 19/Regions.w"
inference_subject *rm = Data__Instances__as_subject(I1);
specification *spec = Data__Instances__get_value(I0);
Calculus__Propositions__assert_kind_of_object(I1, K_room);
World__Inferences__draw_property(rm, P_map_region, spec);
}
#line 244 "inform7/Chapter 19/Regions.w"
;
} else {
Problems__sentence_problem(_P_(C19RegionRelation),
"regions can only contain rooms",
"and have no other relationships.");
}
return TRUE;
}
return FALSE;
}
#line 292 "inform7/Chapter 19/Regions.w"
instance *Plugins__Regions__enclosing(instance *reg) {
instance *P = NULL;
if (Plugins__Spatial__object_is_a_room(reg)) P = PF_I(regions, reg)->in_region;
if (Plugins__Regions__object_is_a_region(reg)) P = Plugins__Spatial__progenitor(reg);
if (Plugins__Regions__object_is_a_region(P) == FALSE) return NULL;
return P;
}
#line 303 "inform7/Chapter 19/Regions.w"
int regions_complete_model(int stage) {
if (stage == 2)
{
#line 314 "inform7/Chapter 19/Regions.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Data__Instances__of_kind(I, K_room)) ||
(Data__Instances__of_kind(I, K_region))) {
parse_node *where = NULL;
specification *val = World__Inferences__get_prop_state_at(
Data__Instances__as_subject(I), P_map_region, &where);
if (val) {
instance *reg =
Specifications__Values__instance_of_CONSTANT_object_if_any(val);
PF_I(regions, I)->in_region = reg;
PF_I(regions, I)->in_region_set_at = where;
}
}
}
#line 304 "inform7/Chapter 19/Regions.w"
;
if (stage == 3)
{
#line 332 "inform7/Chapter 19/Regions.w"
P_regional_found_in = Properties__Valued__new_nameless(
"regional_found_in", K_text);
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (Data__Instances__of_kind(I, K_region)) {
STREAM *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Can't allocate for regional-found-in text");
PROP = Code__Routines__begin(PROP, "*");
STREAM_WRITE(PROP,
"if (TestRegionalContainment(location, %s)) rtrue; rfalse;",
Data__Instances__identifier(I));
PROP = Code__Routines__end(PROP);
STREAM_WRITE(PROP, ",");
Properties__Valued__assert(P_regional_found_in, Data__Instances__as_subject(I),
Specifications__Values__faux_text_literal_from_stream(PROP), CERTAIN_CE);
}
}
#line 305 "inform7/Chapter 19/Regions.w"
;
return FALSE;
}
#line 353 "inform7/Chapter 19/Regions.w"
int regions_add_to_World_index(instance *O) {
if ((O) && (Data__Instances__of_kind(O, K_room))) {
instance *R = Plugins__Regions__enclosing(O);
if (R) Plugins__Map__colour_chip(O, R, PF_I(regions, O)->in_region_set_at);
}
return FALSE;
}
#line 100 "inform7/Chapter 19/The Map.w"
void Plugins__Map__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, map_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_NEW_SUBJECT_NOTIFY, map_new_subject_notify);
PLUGIN_REGISTER(PLUGIN_SET_KIND_NOTIFY, map_set_kind_notify);
PLUGIN_REGISTER(PLUGIN_SET_SUBKIND_NOTIFY, map_set_subkind_notify);
PLUGIN_REGISTER(PLUGIN_ACT_ON_SPECIAL_NPS, map_act_on_special_NPs);
PLUGIN_REGISTER(PLUGIN_CHECK_GOING, map_check_going);
PLUGIN_REGISTER(PLUGIN_COMPILE_MODEL_TABLES, map_compile_model_tables);
PLUGIN_REGISTER(PLUGIN_ESTIMATE_PROPERTY_USAGE, map_estimate_property_usage);
PLUGIN_REGISTER(PLUGIN_COMPILE_OBJECT_HEADER, map_compile_object_header);
PLUGIN_REGISTER(PLUGIN_LOG_INFERENCE_TYPE, map_log_inference_type);
PLUGIN_REGISTER(PLUGIN_INFERENCES_CONTRADICT, map_inferences_contradict);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, map_complete_model);
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, map_new_property_notify);
PLUGIN_REGISTER(PLUGIN_PROPERTY_VALUE_NOTIFY, map_property_value_notify);
PLUGIN_REGISTER(PLUGIN_INTERVENE_IN_ASSERTION, map_intervene_in_assertion);
PLUGIN_REGISTER(PLUGIN_ADD_TO_WORLD_INDEX, map_add_to_World_index);
PLUGIN_REGISTER(PLUGIN_ANNOTATE_IN_WORLD_INDEX, map_annotate_in_World_index);
}
#line 123 "inform7/Chapter 19/The Map.w"
map_data *map_plugin_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;
Plugins__Map__initialise_mapping_data(md);
return md;
}
#line 143 "inform7/Chapter 19/The Map.w"
int map_log_inference_type(int it) {
switch(it) {
case DIRECTION_INF: LOG("DIRECTION_INF"); return TRUE;
}
return FALSE;
}
#line 156 "inform7/Chapter 19/The Map.w"
int 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 171 "inform7/Chapter 19/The Map.w"
int notable_map_kinds_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 174 "inform7/Chapter 19/The Map.w"
#line 178 "inform7/Chapter 19/The Map.w"
int map_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) {
if (parse_nt_against_word_range(notable_map_kinds_NTM, w1, w2, 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 191 "inform7/Chapter 19/The Map.w"
int map_set_subkind_notify(kind *sub, kind *super) {
if ((sub == K_direction) && (super != K_object)) {
Problems__sentence_problem(_P_(C19DirectionAdrift),
"'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;
}
return FALSE;
}
#line 206 "inform7/Chapter 19/The Map.w"
int map_new_subject_notify(inference_subject *subj) {
CREATE_PF_DATA(map, subj);
return FALSE;
}
#line 214 "inform7/Chapter 19/The Map.w"
int Plugins__Map__object_is_a_direction(instance *I) {
if ((Config__Plugins__plugged_in(map_plugin)) && (K_direction) && (I) &&
(Data__Instances__of_kind(I, K_direction)))
return TRUE;
return FALSE;
}
#line 224 "inform7/Chapter 19/The Map.w"
int Plugins__Map__object_is_a_door(instance *I) {
if ((Config__Plugins__plugged_in(map_plugin)) && (K_door) && (I) &&
(Data__Instances__of_kind(I, K_door)))
return TRUE;
return FALSE;
}
#line 239 "inform7/Chapter 19/The Map.w"
int Plugins__Map__is_a_direction(inference_subject *infs) {
if (K_direction == NULL) return FALSE; /* in particular, if we aren't using the IF model */
return World__Subjects__is_within(infs, Kinds__as_subject(K_direction));
}
#line 249 "inform7/Chapter 19/The Map.w"
int registered_directions = 0; /* next direction number to be free */
#line 256 "inform7/Chapter 19/The Map.w"
int notable_map_directions_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 259 "inform7/Chapter 19/The Map.w"
#line 263 "inform7/Chapter 19/The Map.w"
int map_set_kind_notify(instance *I, kind *k) {
kind *kw = Data__Instances__kind(I);
if ((!(Kinds__le(kw, K_direction))) &&
(Kinds__le(k, K_direction))) {
int w1, w2;
Data__Instances__get_name(I, &w1, &w2, FALSE);
{
#line 285 "inform7/Chapter 19/The Map.w"
if (w1 < 0) {
Problems__sentence_problem(_P_(C19NamelessDirection),
"nameless directions are not allowed",
"so writing something like 'There is a direction.' is forbidden.");
return TRUE;
}
if (w2 >= w1 + MAX_WORDS_IN_DIRECTION) {
Problems__sentence_problem(_P_(C19DirectionTooLong),
"although direction names can be really quite long in today's Inform",
"they can't be as long as that.");
return TRUE;
}
}
#line 269 "inform7/Chapter 19/The Map.w"
;
if (parse_nt_against_word_range(notable_map_directions_NTM, w1, w2, NULL, NULL)) {
switch (most_recent_result) {
case 0: I_up = I; break;
case 1: I_down = I; break;
}
}
Plugins__Naming__object_takes_definite_article(Data__Instances__as_subject(I));
{
#line 301 "inform7/Chapter 19/The Map.w"
int dn = registered_directions++;
PF_I(map, I)->direction_index = dn;
char i6_identifier_constant[32];
sprintf(i6_identifier_constant, "DirectionObject_%d", dn);
Plugins__Map__Relations__make_mapped_predicate(I, i6_identifier_constant);
}
#line 277 "inform7/Chapter 19/The Map.w"
;
}
return FALSE;
}
#line 313 "inform7/Chapter 19/The Map.w"
int map_compile_object_header(OUTPUT_STREAM, instance *I) {
if (Plugins__Map__object_is_a_direction(I)) {
WRITE("Object %s \"\" Compass", Data__Instances__identifier(I));
return TRUE;
}
return FALSE;
}
#line 335 "inform7/Chapter 19/The Map.w"
void build_exits_array(void) {
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__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 = World__Subjects__as_instance(infs1);
if (infs2) dir = World__Subjects__as_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 360 "inform7/Chapter 19/The Map.w"
int map_compile_model_tables(OUTPUT_STREAM) {
{
#line 369 "inform7/Chapter 19/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, Data__Instances__identifier(I));
}
#line 361 "inform7/Chapter 19/The Map.w"
;
{
#line 383 "inform7/Chapter 19/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 (Plugins__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", Data__Instances__identifier(to));
else
WRITE(" 0");
}
words_used++;
WRITE(" ! Exits from: %s\n", Data__Instances__identifier(I));
}
WRITE(";\n\n");
Code__VirtualMachines__note_usage("map", -1, -1, "map of rooms and doors",
words_used, 0, FALSE);
}
}
#line 362 "inform7/Chapter 19/The Map.w"
;
return FALSE;
}
#line 416 "inform7/Chapter 19/The Map.w"
void Plugins__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 427 "inform7/Chapter 19/The Map.w"
int notable_map_properties_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 430 "inform7/Chapter 19/The Map.w"
#line 434 "inform7/Chapter 19/The Map.w"
int map_new_property_notify(property *prn) {
if (parse_nt_against_word_range(notable_map_properties_NTM, prn->word_ref1, prn->word_ref2, NULL, NULL)) {
switch (most_recent_result) {
case 0: P_opposite = prn; break;
case 1: P_other_side = prn; break;
}
}
return FALSE;
}
#line 453 "inform7/Chapter 19/The Map.w"
int map_property_value_notify(property *prn, specification *val) {
if (prn == P_other_side) {
instance *I = Specifications__Values__instance_of_CONSTANT_object_if_any(val);
if (I) {
World__Inferences__draw(IS_ROOM_INF, Data__Instances__as_subject(I), CERTAIN_CE,
NULL, NULL);
}
}
return FALSE;
}
#line 471 "inform7/Chapter 19/The Map.w"
void Plugins__Map__set_found_in(instance *I, STREAM *S) {
if (P_found_in == NULL)
P_found_in = Properties__Valued__new_nameless("found_in",
K_value);
if (World__Inferences__get_prop_state(
Data__Instances__as_subject(I), P_found_in))
internal_error("rival found_in interpretations");
Properties__Valued__assert(P_found_in, Data__Instances__as_subject(I),
Specifications__Values__faux_text_literal_from_stream(S), CERTAIN_CE);
}
#line 488 "inform7/Chapter 19/The Map.w"
instance *Plugins__Map__get_value_of_opposite_property(instance *I) {
specification *val = World__Inferences__get_prop_state(
Data__Instances__as_subject(I), P_opposite);
if (val) return Specifications__Values__instance_of_CONSTANT_object_if_any(val);
return NULL;
}
#line 498 "inform7/Chapter 19/The Map.w"
int map_estimate_property_usage(kind *k, int *words_used) {
if (Kinds__eq(k, K_door)) *words_used += 14;
if (Kinds__eq(k, K_room)) *words_used += 2;
return FALSE;
}
#line 508 "inform7/Chapter 19/The Map.w"
int notable_map_noun_phrases_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 511 "inform7/Chapter 19/The Map.w"
#line 515 "inform7/Chapter 19/The Map.w"
int map_act_on_special_NPs(parse_node *p) {
if (parse_nt_against_word_range(notable_map_noun_phrases_NTM, p->word_ref1, p->word_ref2, NULL, NULL)) {
switch (most_recent_result) {
case 0:
if (I_down) {
Parser__Nodes__noun_from_infs(p, Data__Instances__as_subject(I_down));
return TRUE;
}
break;
case 1:
if (I_up) {
Parser__Nodes__noun_from_infs(p, Data__Instances__as_subject(I_up));
return TRUE;
}
break;
}
}
return FALSE;
}
#line 538 "inform7/Chapter 19/The Map.w"
int map_check_going(specification *from, specification *to,
specification *by, specification *through, specification *pushing) {
if (Plugins__Actions__Patterns__check_going(from, "from",
K_room, K_region) == FALSE) return FALSE;
if (Plugins__Actions__Patterns__check_going(to, "to",
K_room, K_region) == FALSE) return FALSE;
if (Plugins__Actions__Patterns__check_going(by, "by",
K_thing, NULL) == FALSE) return FALSE;
if (Plugins__Actions__Patterns__check_going(through, "through",
K_door, NULL) == FALSE) return FALSE;
if (Plugins__Actions__Patterns__check_going(pushing, "with",
K_thing, NULL) == FALSE) return FALSE;
return TRUE;
}
#line 571 "inform7/Chapter 19/The Map.w"
int map_intervene_in_assertion(parse_node *px, parse_node *py) {
if ((Parser__Nodes__type(px) == PROPER_NOUN_NT) &&
(Parser__Nodes__type(py) == COMMON_NOUN_NT)) {
inference_subject *left_object = Parser__Nodes__get_subject(px);
inference_subject *right_kind = Parser__Nodes__get_subject(py);
if ((Plugins__Map__is_a_direction(left_object)) &&
(right_kind != Kinds__as_subject(K_direction))) {
Parser__Assertions__convert_instance_to_nounphrase(py, NULL);
return FALSE;
}
if (Parser__Nodes__int_annotation(px, nowhere_ANNOT)) {
Problems__assertion_problem(_P_(C19NowhereDescribed),
"'nowhere' cannot be made specific",
"and so cannot have specific properties or be of any given kind.");
return TRUE;
}
}
return FALSE;
}
#line 601 "inform7/Chapter 19/The Map.w"
int oneway_map_connections_only = FALSE;
void Plugins__Map__enter_one_way_mode(void) { oneway_map_connections_only = TRUE; }
void Plugins__Map__exit_one_way_mode(void) { oneway_map_connections_only = FALSE; }
#line 612 "inform7/Chapter 19/The Map.w"
void Plugins__Map__connect(inference_subject *i_from, inference_subject *i_to,
inference_subject *i_dir) {
instance *go_from = World__Subjects__as_instance(i_from);
instance *go_to = World__Subjects__as_instance(i_to);
instance *forwards_dir = World__Subjects__as_instance(i_dir);
if (Data__Instances__of_kind(forwards_dir, K_direction) == FALSE)
internal_error("unknown direction");
instance *reverse_dir = Plugins__Map__get_value_of_opposite_property(forwards_dir);
oneway_map_connection(go_from, go_to, forwards_dir, CERTAIN_CE);
if ((reverse_dir) && (go_to) && (oneway_map_connections_only == FALSE)) {
if (Data__Instances__of_kind(reverse_dir, K_direction) == FALSE) {
Problems__quote_object(1, forwards_dir);
Problems__quote_object(2, reverse_dir);
Problems__handmade_problem(_P_(C19OppositeNotDirection));
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 oneway_map_connection(go_to, go_from, reverse_dir, LIKELY_CE);
}
}
void oneway_map_connection(instance *go_from, instance *go_to,
instance *forwards_dir, int certainty_level) {
binary_predicate *bp = Plugins__Map__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_true_about(
Calculus__Propositions__to_set_simple_relation(bp, go_to),
Data__Instances__as_subject(go_from), certainty_level);
prevailing_mood = x;
}
#line 654 "inform7/Chapter 19/The Map.w"
int map_complete_model(int stage) {
switch (stage) {
case 2:
{
#line 683 "inform7/Chapter 19/The Map.w"
P_room_index = Properties__Valued__new_nameless("room_index", K_number);
specification *minus_one = Specifications__Values__new_integer_literal(-1);
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (Plugins__Spatial__object_is_a_room(I))
Properties__Valued__assert(P_room_index,
Data__Instances__as_subject(I), minus_one, CERTAIN_CE);
}
#line 657 "inform7/Chapter 19/The Map.w"
;
{
#line 696 "inform7/Chapter 19/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), DIRECTION_INF) {
inference_subject *infs1;
World__Inferences__get_references(inf, &infs1, NULL);
instance *to = World__Subjects__as_instance(infs1);
if ((Plugins__Spatial__object_is_a_room(I)) && (to) &&
(Plugins__Map__object_is_a_door(to) == FALSE) &&
(Plugins__Spatial__object_is_a_room(to) == FALSE))
Problems__contradiction_problem(_P_(C19BadMapCell),
Data__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 ((Plugins__Map__object_is_a_door(I)) &&
(Plugins__Spatial__object_is_a_room(to) == FALSE))
Problems__object_problem(_P_(C19DoorToNonRoom),
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 658 "inform7/Chapter 19/The Map.w"
;
if (problem_count > 0) break;
{
#line 725 "inform7/Chapter 19/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (Plugins__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, Data__Instances__as_subject(I), DIRECTION_INF) {
inference_subject *infs1, *infs2;
World__Inferences__get_references(inf, &infs1, &infs2);
instance *to = World__Subjects__as_instance(infs1);
instance *dir = World__Subjects__as_instance(infs2);
LOG("Okay, $O to $O\n", I, to);
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 777 "inform7/Chapter 19/The Map.w"
Problems__object_problem(_P_(C19DoorUnconnected),
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 770 "inform7/Chapter 19/The Map.w"
;
if (connections_in > 2)
{
#line 787 "inform7/Chapter 19/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__handmade_problem(_P_(C19DoorOverconnected));
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 771 "inform7/Chapter 19/The Map.w"
;
}
}
#line 660 "inform7/Chapter 19/The Map.w"
;
if (problem_count > 0) break;
{
#line 807 "inform7/Chapter 19/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (Plugins__Spatial__object_is_a_room(I)) {
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Data__Instances__as_subject(I), DIRECTION_INF) {
inference_subject *infs1;
World__Inferences__get_references(inf, &infs1, NULL);
instance *to = World__Subjects__as_instance(infs1);
if (Plugins__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__handmade_problem(_P_(C19RoomTwistyDoor));
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__handmade_problem(_P_(C19RoomMissingDoor));
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 662 "inform7/Chapter 19/The Map.w"
;
if (problem_count > 0) break;
{
#line 849 "inform7/Chapter 19/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Plugins__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(
Data__Instances__as_subject(I), P_other_side)))
Problems__object_problem(_P_(C19BothWaysDoor),
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 664 "inform7/Chapter 19/The Map.w"
;
if (problem_count > 0) break;
{
#line 872 "inform7/Chapter 19/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Plugins__Map__object_is_a_door(I)) &&
(Plugins__Spatial__progenitor(I)) &&
(Plugins__Spatial__progenitor(I) != PF_I(map, I)->map_connection_a) &&
(Plugins__Spatial__progenitor(I) != PF_I(map, I)->map_connection_b))
Problems__object_problem(_P_(C19DoorInThirdRoom),
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 666 "inform7/Chapter 19/The Map.w"
;
if (problem_count > 0) break;
{
#line 888 "inform7/Chapter 19/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Plugins__Map__object_is_a_door(I)) &&
(PF_I(map, I)->map_connection_b == NULL) &&
(Plugins__Spatial__progenitor(I) == NULL))
Plugins__Spatial__set_progenitor(I, PF_I(map, I)->map_connection_a, NULL);
}
#line 668 "inform7/Chapter 19/The Map.w"
;
{
#line 901 "inform7/Chapter 19/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 (Plugins__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 923 "inform7/Chapter 19/The Map.w"
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");
STREAM_WRITE(PROP, "%s %s",
Data__Instances__identifier(R1), Data__Instances__identifier(R2));
Plugins__Map__set_found_in(I, PROP);
}
#line 912 "inform7/Chapter 19/The Map.w"
;
{
#line 934 "inform7/Chapter 19/The Map.w"
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 = Code__Routines__begin(PROP, "*");
Code__LocalVariables__add_internal_local_c("loc", "room of actor");
STREAM_WRITE(PROP, "loc = location;\n");
STREAM_WRITE(PROP, "if (loc == thedark) loc = real_location;\n");
STREAM_WRITE(PROP, "if (loc == %s) return %s; return %s;",
Data__Instances__identifier(R1),
Data__Instances__identifier(
Plugins__Map__get_value_of_opposite_property(D1)),
Data__Instances__identifier(
Plugins__Map__get_value_of_opposite_property(D2)));
PROP = Code__Routines__end(PROP);
STREAM_WRITE(PROP, ",");
Properties__Valued__assert(P_door_dir, Data__Instances__as_subject(I),
Specifications__Values__faux_text_literal_from_stream(PROP), CERTAIN_CE);
}
#line 913 "inform7/Chapter 19/The Map.w"
;
{
#line 957 "inform7/Chapter 19/The Map.w"
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 = Code__Routines__begin(PROP, "*");
Code__LocalVariables__add_internal_local_c("loc", "room of actor");
STREAM_WRITE(PROP, "loc = location;\n");
STREAM_WRITE(PROP, "if (loc == thedark) loc = real_location;\n");
STREAM_WRITE(PROP, "if (loc == %s) return %s; return %s;",
Data__Instances__identifier(R1),
Data__Instances__identifier(R2), Data__Instances__identifier(R1));
PROP = Code__Routines__end(PROP);
STREAM_WRITE(PROP, ",");
Properties__Valued__assert(P_door_to, Data__Instances__as_subject(I),
Specifications__Values__faux_text_literal_from_stream(PROP), CERTAIN_CE);
}
#line 914 "inform7/Chapter 19/The Map.w"
;
} else if (R1) {
{
#line 984 "inform7/Chapter 19/The Map.w"
instance *backwards = Plugins__Map__get_value_of_opposite_property(D1);
if (backwards) {
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");
STREAM_WRITE(PROP, "%s", Data__Instances__identifier(backwards));
Properties__Valued__assert(P_door_dir, Data__Instances__as_subject(I),
Specifications__Values__new_text_literal_from_stream(PROP), CERTAIN_CE);
}
}
#line 916 "inform7/Chapter 19/The Map.w"
;
}
}
}
#line 669 "inform7/Chapter 19/The Map.w"
;
break;
case 4: build_exits_array(); break;
}
return FALSE;
}
#line 997 "inform7/Chapter 19/The Map.w"
int map_add_to_World_index(instance *O) {
if ((O) && (Data__Instances__of_kind(O, K_room))) {
Plugins__Map__index_room_connections(O);
}
return FALSE;
}
int map_annotate_in_World_index(instance *O) {
if ((O) && (Data__Instances__of_kind(O, K_door))) {
instance *A = NULL, *B = NULL;
Plugins__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) {
specification *S = World__Inferences__get_prop_state(
Data__Instances__as_subject(O), P_other_side);
X = Specifications__Values__instance_of_CONSTANT_object_if_any(S);
}
if (X == NULL) INDEX("nowhere");
else Data__Instances__index_name(X);
INDEX("</i>");
return TRUE;
}
return FALSE;
}
#line 25 "inform7/Chapter 19/Map Connection Relations.w"
void Plugins__Map__create_relations(void) {
R_adjacency =
Semantics__BPs__make_pair(SPATIAL_KBP,
Semantics__BPs__Terms__new(infs_room),
Semantics__BPs__Terms__new(infs_room),
"adjacent-to", "adjacent-from",
NULL, NULL, Code__Schemas__new("TestAdjacency(*1,*2)"),
Text__Languages__wording(relation_names_NTM, ADJACENCY_RELATION_NAME));
}
#line 38 "inform7/Chapter 19/Map Connection Relations.w"
int Plugins__Map__assert_relations(binary_predicate *relation, instance *I0, instance *I1) {
return FALSE;
}
#line 47 "inform7/Chapter 19/Map Connection Relations.w"
void Plugins__Map__Relations__create_initial_stock(void) {
}
#line 58 "inform7/Chapter 19/Map Connection Relations.w"
binary_predicate *Plugins__Map__create_sketchy_mapping_direction(int w1, int w2) {
binary_predicate *bp;
{
#line 110 "inform7/Chapter 19/Map Connection Relations.w"
if (w2 >= w1 + MAX_WORDS_IN_DIRECTION)
w2 = w1 + MAX_WORDS_IN_DIRECTION - 1; /* just truncate for now */
char dln[MAX_WORDS_IN_DIRECTION*MAX_WORD_LENGTH+10]; /* for debugging log, e.g., "north-map" */
Text__print_text_to_string(w1, w2, dln); sprintf(dln + Platform__strlen(dln), "-map");
int i;
for (i=0; dln[i]; i++) if (dln[i] == ' ') dln[i] = '-';
bp_term_details room_term = Semantics__BPs__Terms__new(NULL);
bp = Semantics__BPs__make_pair(MAP_CONNECTING_KBP,
room_term, room_term, dln, NULL, NULL, NULL, NULL,
Text__Languages__merge(mapping_relation_construction_NTM, 0,
Text__Words__from_range(w1, w2)));
int mpc_form = 0;
if (parse_nt_against_word_range(notable_directions_NTM, w1, w2, NULL, NULL)) mpc_form = 1;
Semantics__PrepositionUsage__register(
Text__Languages__merge(mapping_preposition_construction_NTM, mpc_form,
Text__Words__from_range(w1, w2)),
FALSE, bp, FALSE, FALSE);
}
#line 60 "inform7/Chapter 19/Map Connection Relations.w"
;
return bp;
}
#line 91 "inform7/Chapter 19/Map Connection Relations.w"
int mapping_relation_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 93 "inform7/Chapter 19/Map Connection Relations.w"
int mapping_preposition_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 97 "inform7/Chapter 19/Map Connection Relations.w"
#line 103 "inform7/Chapter 19/Map Connection Relations.w"
int notable_directions_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 106 "inform7/Chapter 19/Map Connection Relations.w"
#line 142 "inform7/Chapter 19/Map Connection Relations.w"
int mmp_call_counter = 0;
void Plugins__Map__Relations__make_mapped_predicate(instance *I, char *ident) {
int w1, w2;
Data__Instances__get_name(I, &w1, &w2, FALSE);
if ((w1<0) || (w2 >= w1+MAX_WORDS_IN_DIRECTION)) internal_error("bad direction name");
binary_predicate *bp = Parser__Sentences__relation_noticed(mmp_call_counter++);
if (bp == NULL) {
LOG("Improper text: $W\n", w1, w2);
Problems__sentence_problem(_P_(C19ImproperlyMadeDirection),
"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] = Semantics__BPs__Terms__new(NULL);
bp->term_details[1] = Semantics__BPs__Terms__new(NULL);
Semantics__BPs__set_index_details(bp, "room/door", "room/door");
bp->test_function = Code__Schemas__new("(MapConnection(*2,%s) == *1)", ident);
bp->make_true_function = Code__Schemas__new("AssertMapConnection(*2,%s,*1)", ident);
bp->make_false_function = Code__Schemas__new("AssertMapUnconnection(*2,%s,*1)", ident);
PF_I(map, I)->direction_relation = bp;
}
#line 172 "inform7/Chapter 19/Map Connection Relations.w"
void Plugins__Map__Relations__create_second_stock(void) {
}
#line 180 "inform7/Chapter 19/Map Connection Relations.w"
int Plugins__Map__Relations__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__compatible(kinds_of_terms[t], K_room) == NEVER_MATCH) &&
(Kinds__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__issue_bp_typecheck_error(bp, kinds_of_terms[0], kinds_of_terms[1], tck);
return NEVER_MATCH;
}
return ALWAYS_MATCH;
}
#line 201 "inform7/Chapter 19/Map Connection Relations.w"
int Plugins__Map__Relations__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
instance *o_dir = Plugins__Map__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);
World__Inferences__draw(DIRECTION_INF, infs_from, prevailing_mood,
infs_to, o_dir?(Data__Instances__as_subject(o_dir)):NULL);
return TRUE;
}
#line 219 "inform7/Chapter 19/Map Connection Relations.w"
int Plugins__Map__Relations__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) {
return FALSE;
}
#line 226 "inform7/Chapter 19/Map Connection Relations.w"
int Plugins__Map__Relations__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 234 "inform7/Chapter 19/Map Connection Relations.w"
binary_predicate *Plugins__Map__get_mapping_relation(instance *dir) {
if (dir == NULL) return NULL;
return PF_I(map, dir)->direction_relation;
}
instance *Plugins__Map__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 61 "inform7/Chapter 19/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 70 "inform7/Chapter 19/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 83 "inform7/Chapter 19/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 110 "inform7/Chapter 19/Spatial Geometry.w"
int Geometry__vec_length_squared(vector V) {
return V.x*V.x + V.y*V.y + V.z*V.z;
}
float vec_length(vector V) {
return (float) (sqrt(Geometry__vec_length_squared(V)));
}
#line 127 "inform7/Chapter 19/Spatial Geometry.w"
float Geometry__vec_angular_separation(vector E, vector D) {
float E_distance = vec_length(E);
float uex = E.x/E_distance, uey = E.y/E_distance, uez = E.z/E_distance;
float D_distance = 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 140 "inform7/Chapter 19/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 163 "inform7/Chapter 19/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 179 "inform7/Chapter 19/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 189 "inform7/Chapter 19/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 206 "inform7/Chapter 19/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 227 "inform7/Chapter 19/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 19/Spatial Map.w"
int spatial_coordinates_established = FALSE;
int partitioned_into_components = FALSE;
void Plugins__Map__establish_spatial_coordinates(void) {
if (spatial_coordinates_established) return;
if (Log__Aspects__on(SPATIAL_MAP_DA)) log_precis_of_map();
Universe = Geometry__empty_cuboid();
{
#line 506 "inform7/Chapter 19/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 = room_exit_as_indexed(R, i, NULL);
if (T)
{
#line 534 "inform7/Chapter 19/Spatial Map.w"
int back = Plugins__Map__opposite(i);
int cw = rotate_direction(back, 1); /* clockwise one place */
int cwcw = rotate_direction(cw, 1); /* clockwise twice */
int ccw = rotate_direction(back, -1); /* counterclockwise once */
int ccwccw = rotate_direction(ccw, -1); /* counterclockwise twice */
instance *backstep = room_exit_as_indexed(T, back, NULL);
{
#line 557 "inform7/Chapter 19/Spatial Map.w"
if ((backstep == R) &&
(cwcw >= 0) &&
(room_exit_as_indexed(T, cwcw, NULL) == R) &&
(room_exit_as_indexed(T, cw, NULL) == NULL) &&
(room_exit_as_indexed(R, Plugins__Map__opposite(cwcw), NULL) == T) &&
(room_exit_as_indexed(T, Plugins__Map__opposite(cw), NULL) == NULL)) {
form_spatial_relationship(R, Plugins__Map__opposite(cw), T);
continue;
}
if ((backstep == R) &&
(ccwccw >= 0) &&
(room_exit_as_indexed(T, ccwccw, NULL) == R) &&
(room_exit_as_indexed(T, ccw, NULL) == NULL) &&
(room_exit_as_indexed(R, Plugins__Map__opposite(ccwccw), NULL) == T) &&
(room_exit_as_indexed(T, Plugins__Map__opposite(ccw), NULL) == NULL)) {
form_spatial_relationship(R, Plugins__Map__opposite(ccw), T);
continue;
}
}
#line 542 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 579 "inform7/Chapter 19/Spatial Map.w"
if (backstep == R) {
form_spatial_relationship(R, i, T);
continue;
}
}
#line 543 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 589 "inform7/Chapter 19/Spatial Map.w"
/* a deformed 2-way connection made up of 1-way connections */
if ((cwcw >= 0) &&
(room_exit_as_indexed(T, cwcw, NULL) == R) &&
(room_exit_as_indexed(T, cw, NULL) == NULL) &&
(room_exit_as_indexed(R, Plugins__Map__opposite(cwcw), NULL) == T) &&
(room_exit_as_indexed(T, Plugins__Map__opposite(cw), NULL) == NULL)) {
form_spatial_relationship(R, Plugins__Map__opposite(cw), T);
continue;
}
if ((ccwccw >= 0) &&
(room_exit_as_indexed(T, ccwccw, NULL) == R) &&
(room_exit_as_indexed(T, ccw, NULL) == NULL) &&
(room_exit_as_indexed(R, Plugins__Map__opposite(ccwccw), NULL) == T) &&
(room_exit_as_indexed(T, Plugins__Map__opposite(ccw), NULL) == NULL)) {
form_spatial_relationship(R, Plugins__Map__opposite(ccw), T);
continue;
}
}
#line 544 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 614 "inform7/Chapter 19/Spatial Map.w"
int j, two_ways = 0;
LOOP_OVER_LATTICE_DIRECTIONS(j)
if ((room_exit_as_indexed(T, j, NULL) == R) &&
(room_exit_as_indexed(R, Plugins__Map__opposite(j), NULL) == T))
two_ways++;
if ((two_ways == 0) && (backstep == NULL))
form_spatial_relationship(R, i, T);
}
#line 545 "inform7/Chapter 19/Spatial Map.w"
;
}
#line 516 "inform7/Chapter 19/Spatial Map.w"
;
}
}
}
#line 148 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 890 "inform7/Chapter 19/Spatial Map.w"
create_map_component_around(benchmark_room);
instance *R;
LOOP_OVER_ROOMS(R)
if (PF_I(map, R)->submap == NULL)
create_map_component_around(R);
}
#line 149 "inform7/Chapter 19/Spatial Map.w"
;
partitioned_into_components = TRUE;
{
#line 995 "inform7/Chapter 19/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);
lock_positions_in_submap(sub); /* $O(R)$ running time */
establish_natural_lengths(sub); /* $O(R)$ running time */
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 19/Spatial Map.w"
;
{
#line 2380 "inform7/Chapter 19/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 19/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 *), compare_components);
}
#line 2383 "inform7/Chapter 19/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 19/Spatial Map.w"
if (previous_mc) {
int x_max = box.corner1.x - sub->bounds.corner0.x + 1;
if ((sub->bounds.population == 1) && (component_is_isolated(sub)))
{
#line 2442 "inform7/Chapter 19/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) && (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);
}
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 19/Spatial Map.w"
else if (component_is_adjoining(sub))
{
#line 2471 "inform7/Chapter 19/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;
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 19/Spatial Map.w"
move_component(sub, Offset);
int s = find_component_placement_heat(sub);
if (s < min_s) {
min_s = s; Best_offset = Offset;
}
move_component(sub, Geometry__vec_negate(Offset));
}
#line 2488 "inform7/Chapter 19/Spatial Map.w"
;
}
}
move_component(sub, Best_offset);
}
#line 2415 "inform7/Chapter 19/Spatial Map.w"
else
{
#line 2427 "inform7/Chapter 19/Spatial Map.w"
LOGIF(SPATIAL_MAP, "Component %d (size %d): side by side strategy\n",
sub->allocation_id, sub->bounds.population);
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 19/Spatial Map.w"
;
}
Geometry__merge_cuboid(&box, sub->bounds);
previous_mc = sub;
sub->positioned = TRUE;
}
#line 2394 "inform7/Chapter 19/Spatial Map.w"
;
for (j=ncom-1; j>=0; j--) {
sub = sorted[j];
if ((sub->positioned == FALSE) &&
(no_links_to_placed_components(sub) == 1)) {
{
#line 2410 "inform7/Chapter 19/Spatial Map.w"
if (previous_mc) {
int x_max = box.corner1.x - sub->bounds.corner0.x + 1;
if ((sub->bounds.population == 1) && (component_is_isolated(sub)))
{
#line 2442 "inform7/Chapter 19/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) && (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);
}
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 19/Spatial Map.w"
else if (component_is_adjoining(sub))
{
#line 2471 "inform7/Chapter 19/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;
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 19/Spatial Map.w"
move_component(sub, Offset);
int s = find_component_placement_heat(sub);
if (s < min_s) {
min_s = s; Best_offset = Offset;
}
move_component(sub, Geometry__vec_negate(Offset));
}
#line 2488 "inform7/Chapter 19/Spatial Map.w"
;
}
}
move_component(sub, Best_offset);
}
#line 2415 "inform7/Chapter 19/Spatial Map.w"
else
{
#line 2427 "inform7/Chapter 19/Spatial Map.w"
LOGIF(SPATIAL_MAP, "Component %d (size %d): side by side strategy\n",
sub->allocation_id, sub->bounds.population);
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 19/Spatial Map.w"
;
}
Geometry__merge_cuboid(&box, sub->bounds);
previous_mc = sub;
sub->positioned = TRUE;
}
#line 2399 "inform7/Chapter 19/Spatial Map.w"
;
}
}
}
}
Memory__I7_free(sorted, INDEX_SORTING_MREASON);
}
#line 152 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 2710 "inform7/Chapter 19/Spatial Map.w"
Universe = Geometry__empty_cuboid();
instance *R;
LOOP_OVER_ROOMS(R)
Geometry__adjust_cuboid(&Universe, Room_position(R));
}
#line 153 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 2720 "inform7/Chapter 19/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)
translate_room(R, D_vector);
}
}
#line 154 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 2710 "inform7/Chapter 19/Spatial Map.w"
Universe = Geometry__empty_cuboid();
instance *R;
LOOP_OVER_ROOMS(R)
Geometry__adjust_cuboid(&Universe, Room_position(R));
}
#line 155 "inform7/Chapter 19/Spatial Map.w"
;
spatial_coordinates_established = TRUE;
}
#line 169 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__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;
Plugins__Map__prepare_map_parameter_scope(&(md->local_map_parameters));
}
#line 187 "inform7/Chapter 19/Spatial Map.w"
void set_room_position(instance *R, vector P) {
vector O = Room_position(R);
PF_I(map, R)->position = P;
if (PF_I(map, R)->submap) move_room_within_submap(PF_I(map, R)->submap, O, P);
}
void set_room_position_breaking_cache(instance *R, vector P) {
PF_I(map, R)->position = P;
}
#line 201 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__lock_exit_in_place(instance *I, int exit, instance *I2) {
lock_one_exit(I2, exit, I);
lock_one_exit(I, Plugins__Map__opposite(exit), I2);
}
void lock_one_exit(instance *F, int exit, instance *T) {
LOGIF(SPATIAL_MAP, "Mapping clue: put $O to the %s of $O\n",
T, usual_Inform_direction_name(exit), F);
PF_I(map, F)->lock_exits[exit] = T;
}
#line 228 "inform7/Chapter 19/Spatial Map.w"
int story_dir_to_page_dir[MAX_DIRECTIONS];
void Plugins__Map__initialise_page_directions(void) {
int i;
for (i=0; i<registered_directions; i++)
story_dir_to_page_dir[i] = i;
}
#line 244 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__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 *Plugins__Map__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 19/Spatial Map.w"
int Plugins__Map__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 19/Spatial Map.w"
vector Plugins__Map__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 19/Spatial Map.w"
int Plugins__Map__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 19/Spatial Map.w"
int 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 19/Spatial Map.w"
int Plugins__Map__direction_is_lateral(int story_direction) {
return Geometry__vec_lateral(
Plugins__Map__direction_as_vector(story_direction));
}
#line 355 "inform7/Chapter 19/Spatial Map.w"
int direction_is_along_lattice(int story_direction) {
vector D = Plugins__Map__direction_as_vector(story_direction);
if (Geometry__vec_eq(D, Zero_vector)) return FALSE;
return TRUE;
}
#line 383 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__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 19/Spatial Map.w"
char *Plugins__Map__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 *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 19/Spatial Map.w"
void Plugins__Map__establish_benchmark_room(void) {
if (benchmark_room == NULL) {
benchmark_room = Plugins__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 19/Spatial Map.w"
instance *Plugins__Map__room_exit(instance *origin, int dir_num, instance **via) {
if (via) *via = NULL;
if ((origin == NULL) || (Plugins__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 (Plugins__Spatial__object_is_a_room(immediate_destination))
ultimate_destination = immediate_destination;
if (Plugins__Map__object_is_a_door(immediate_destination)) {
if (via) *via = immediate_destination;
instance *A = NULL, *B = NULL;
Plugins__Map__get_door_data(immediate_destination, &A, &B);
if (A == origin) ultimate_destination = B;
if (B == origin) ultimate_destination = A;
}
}
return ultimate_destination;
}
instance *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 = Plugins__Map__room_exit(origin, j, via);
if (I) return I;
}
}
return NULL;
}
#line 626 "inform7/Chapter 19/Spatial Map.w"
void form_spatial_relationship(instance *R, int dir, instance *T) {
PF_I(map, R)->spatial_relationship[dir] = T;
PF_I(map, T)->spatial_relationship[Plugins__Map__opposite(dir)] = R;
}
#line 642 "inform7/Chapter 19/Spatial Map.w"
instance *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 *read_smap_cross(instance *from, int dir) {
if (from == NULL) internal_error("tried to read smap at null room");
drognas_spent++;
instance *to = Plugins__Map__room_exit(from, dir, NULL);
return to;
}
#line 662 "inform7/Chapter 19/Spatial Map.w"
instance *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 19/Spatial Map.w"
connected_submap *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 19/Spatial Map.w"
void 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;
add_room_to_cache(sub, Room_position(R), 1);
}
#line 721 "inform7/Chapter 19/Spatial Map.w"
int 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 19/Spatial Map.w"
void move_room_within_submap(connected_submap *sub, vector O, vector P) {
add_room_to_cache(sub, O, -1);
add_room_to_cache(sub, P, 1);
}
#line 740 "inform7/Chapter 19/Spatial Map.w"
void 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 19/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;
}
}
free_incidence_cache(sub);
sub->incidence_cache = new_cache;
sub->incidence_cache_bounds = new_cuboid;
}
#line 742 "inform7/Chapter 19/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 19/Spatial Map.w"
void 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 19/Spatial Map.w"
void empty_submap(connected_submap *sub) {
sub->first_room_in_submap = NULL;
sub->last_room_in_submap = NULL;
free_incidence_cache(sub);
sub->superpositions = 0;
}
#line 819 "inform7/Chapter 19/Spatial Map.w"
void destroy_submap(connected_submap *sub) {
free_incidence_cache(sub);
DESTROY(sub, connected_submap);
}
#line 829 "inform7/Chapter 19/Spatial Map.w"
void move_component(connected_submap *sub, vector D) {
instance *R;
LOOP_OVER_SUBMAP(R, sub)
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 19/Spatial Map.w"
void 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)
add_room_to_submap(R, Zone1);
else if (PF_I(map, R)->zone == Z2_number)
add_room_to_submap(R, Zone2);
PF_I(map, R)->zone = 0;
}
empty_submap(sub);
}
#line 865 "inform7/Chapter 19/Spatial Map.w"
void 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) {
add_room_to_submap(R, sub);
PF_I(map, R)->zone = Z1_number;
}
if (PF_I(map, R)->submap == Zone2) {
add_room_to_submap(R, sub);
PF_I(map, R)->zone = Z2_number;
}
}
}
#line 905 "inform7/Chapter 19/Spatial Map.w"
void create_map_component_around(instance *at) {
if (PF_I(map, at)->submap == NULL) add_room_to_submap(at, new_submap());
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *locked_to = read_slock(at, i);
if ((locked_to) && (PF_I(map, locked_to)->submap != PF_I(map, at)->submap)) {
add_room_to_submap(locked_to, PF_I(map, at)->submap);
create_map_component_around(locked_to);
}
instance *dest = read_smap(at, i);
if ((dest) && (PF_I(map, dest)->submap != PF_I(map, at)->submap)) {
add_room_to_submap(dest, PF_I(map, at)->submap);
create_map_component_around(dest);
}
}
}
#line 927 "inform7/Chapter 19/Spatial Map.w"
void translate_room(instance *R, vector D) {
set_room_position(R, Geometry__vec_plus(Room_position(R), D));
}
void move_room_to(instance *R, vector P) {
set_room_position(R, P);
move_anything_locked_to(R);
}
#line 947 "inform7/Chapter 19/Spatial Map.w"
void 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;
move_anything_locked_to_r(R);
}
void 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 = read_slock(R, i);
if (F) {
vector D = Plugins__Map__direction_as_vector(i);
set_room_position(F, Geometry__vec_plus(Room_position(R), D));
move_anything_locked_to_r(F);
}
}
}
#line 974 "inform7/Chapter 19/Spatial Map.w"
void 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)
move_anything_locked_to_r(R);
}
#line 1022 "inform7/Chapter 19/Spatial Map.w"
void establish_natural_lengths(connected_submap *sub) {
instance *R;
LOOP_OVER_SUBMAP(R, sub) {
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
if (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 19/Spatial Map.w"
int heat_sum(int h1, int h2) {
int h = h1+h2;
if (h > FUSION_POINT) return FUSION_POINT;
return h;
}
#line 1072 "inform7/Chapter 19/Spatial Map.w"
int find_submap_heat(connected_submap *sub) {
int heat = 0;
sub->bounds = Geometry__empty_cuboid();
instance *R;
LOOP_OVER_SUBMAP(R, sub) {
heat = heat_sum(heat, find_room_heat(R));
Geometry__adjust_cuboid(&(sub->bounds), Room_position(R));
}
int collisions = sub->superpositions;
while (collisions >= 1000) {
heat = heat_sum(heat, 1000*COLLISION_HEAT);
collisions -= 1000;
}
heat = heat_sum(heat, collisions*COLLISION_HEAT);
if (heat == FUSION_POINT) heat = FUSION_POINT + sub->superpositions;
sub->heat = heat;
return heat;
}
#line 1096 "inform7/Chapter 19/Spatial Map.w"
int find_room_heat(instance *R) {
int i, h = 0;
LOOP_OVER_LATTICE_DIRECTIONS(i) h += find_exit_heat(R, i);
return h;
}
#line 1123 "inform7/Chapter 19/Spatial Map.w"
int find_exit_heat(instance *from, int exit) {
drognas_spent++;
instance *to = 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 (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 = Plugins__Map__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 (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 19/Spatial Map.w"
int exit_aligned(instance *from, int exit) {
drognas_spent++;
instance *to = read_smap(from, exit);
if (to == NULL) return TRUE; /* at any rate, not misaligned */
if (from == to) return TRUE; /* ditto */
if (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 = Plugins__Map__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 19/Spatial Map.w"
int unique_Z_number = 1;
void position_submap(connected_submap *sub) {
int initial_heat = 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__Aspects__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) {
cool_submap(sub);
find_submap_heat(sub);
if (sub->heat > 0) {
{
#line 1228 "inform7/Chapter 19/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 = 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 19/Spatial Map.w"
int Z1_count = 0, Z2_count = 0;
if (div_F2) {
int predivision_spending = drognas_spent;
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, usual_Inform_direction_name(div_dir1), div_T1,
div_F2, usual_Inform_direction_name(div_dir2), div_T2,
drognas_spent - predivision_spending);
division_spending += drognas_spent - predivision_spending;
} else {
int predivision_spending = drognas_spent;
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, 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 19/Spatial Map.w"
;
{
#line 1296 "inform7/Chapter 19/Spatial Map.w"
connected_submap *Zone1 = new_submap();
connected_submap *Zone2 = new_submap();
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;
position_submap(Zone1);
position_submap(Zone2);
LOG_OUTDENT;
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);
destroy_submap(Zone1);
destroy_submap(Zone2);
}
#line 1237 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 1337 "inform7/Chapter 19/Spatial Map.w"
int preslide_spending = drognas_spent;
vector Axis = Plugins__Map__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++) {
save_component_positions(sub);
{
#line 1373 "inform7/Chapter 19/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)
translate_room(Z2, D);
}
#line 1348 "inform7/Chapter 19/Spatial Map.w"
;
int h = find_submap_heat(sub);
if ((h < coolest_temperature) || (coolest_temperature == -1)) {
coolest_temperature = h;
coolest_L = L;
}
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 19/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)
translate_room(Z2, D);
}
#line 1363 "inform7/Chapter 19/Spatial Map.w"
;
}
#line 1238 "inform7/Chapter 19/Spatial Map.w"
;
if (find_submap_heat(sub) > 0) radiate_submap(sub);
} else
{
#line 1247 "inform7/Chapter 19/Spatial Map.w"
if (find_submap_heat(sub) > 0) {
quench_submap(sub, NULL, NULL);
if (find_submap_heat(sub) > 0) {
diffuse_submap(sub);
if (find_submap_heat(sub) > 0) {
quench_submap(sub, NULL, NULL);
if (find_submap_heat(sub) > 0) {
radiate_submap(sub);
if (find_submap_heat(sub) >= COLLISION_HEAT)
explode_submap(sub);
}
}
}
}
}
#line 1241 "inform7/Chapter 19/Spatial Map.w"
;
}
#line 1208 "inform7/Chapter 19/Spatial Map.w"
;
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 19/Spatial Map.w"
int 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 19/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 19/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 19/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 19/Spatial Map.w"
;
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 19/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 19/Spatial Map.w"
;
return FALSE;
}
#line 1524 "inform7/Chapter 19/Spatial Map.w"
int 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 = read_slock(at, i);
if (T) {
{
#line 1564 "inform7/Chapter 19/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 19/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 19/Spatial Map.w"
;
continue;
}
}
#line 1537 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 1600 "inform7/Chapter 19/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 19/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 19/Spatial Map.w"
;
PF_I(map, T)->zone = generation + 1;
int rooms_explored_in_the_beyond = 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 19/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 19/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 19/Spatial Map.w"
;
}
}
}
#line 1612 "inform7/Chapter 19/Spatial Map.w"
;
if (locking_to_neighbours == FALSE)
{
#line 1651 "inform7/Chapter 19/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 19/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 19/Spatial Map.w"
else if (no_contacts_found == 1)
{
#line 1689 "inform7/Chapter 19/Spatial Map.w"
if (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] == Plugins__Map__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 19/Spatial Map.w"
;
}
}
#line 1614 "inform7/Chapter 19/Spatial Map.w"
;
}
#line 1538 "inform7/Chapter 19/Spatial Map.w"
;
}
}
locking_to_neighbours = FALSE;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = read_smap(at, i);
if (T) {
{
#line 1564 "inform7/Chapter 19/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 19/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 19/Spatial Map.w"
;
continue;
}
}
#line 1545 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 1600 "inform7/Chapter 19/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 19/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 19/Spatial Map.w"
;
PF_I(map, T)->zone = generation + 1;
int rooms_explored_in_the_beyond = 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 19/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 19/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 19/Spatial Map.w"
;
}
}
}
#line 1612 "inform7/Chapter 19/Spatial Map.w"
;
if (locking_to_neighbours == FALSE)
{
#line 1651 "inform7/Chapter 19/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 19/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 19/Spatial Map.w"
else if (no_contacts_found == 1)
{
#line 1689 "inform7/Chapter 19/Spatial Map.w"
if (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] == Plugins__Map__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 19/Spatial Map.w"
;
}
}
#line 1614 "inform7/Chapter 19/Spatial Map.w"
;
}
#line 1546 "inform7/Chapter 19/Spatial Map.w"
;
}
}
LOG_OUTDENT;
return rooms_visited + 1;
}
#line 1739 "inform7/Chapter 19/Spatial Map.w"
int 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 = divide_into_zones_onecut_r(R1, NULL, R1, R2, &contacts);
if (contacts > 0) return FALSE;
*Z2_count = 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 19/Spatial Map.w"
int 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 = read_slock(at, i);
if (T)
{
#line 1786 "inform7/Chapter 19/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 +=
divide_into_zones_onecut_r(T, at, our_capital, foreign_capital, borders);
}
#line 1774 "inform7/Chapter 19/Spatial Map.w"
;
}
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = read_smap(at, i);
if (T)
{
#line 1786 "inform7/Chapter 19/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 +=
divide_into_zones_onecut_r(T, at, our_capital, foreign_capital, borders);
}
#line 1778 "inform7/Chapter 19/Spatial Map.w"
;
}
return rooms_visited + 1;
}
#line 1800 "inform7/Chapter 19/Spatial Map.w"
void 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;
divide_into_zones_twocut_r(div_F1, div_F1, div_T1, other_F, div_T2);
divide_into_zones_twocut_r(div_T1, div_F1, div_T1, other_F, div_T2);
}
#line 1813 "inform7/Chapter 19/Spatial Map.w"
void 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 = read_slock(at, i);
if (T)
{
#line 1829 "inform7/Chapter 19/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;
divide_into_zones_twocut_r(T, not_X1, not_Y1, not_X2, not_Y2);
}
}
#line 1818 "inform7/Chapter 19/Spatial Map.w"
;
}
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = read_smap(at, i);
if (T)
{
#line 1829 "inform7/Chapter 19/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;
divide_into_zones_twocut_r(T, not_X1, not_Y1, not_X2, not_Y2);
}
}
#line 1822 "inform7/Chapter 19/Spatial Map.w"
;
}
}
#line 1853 "inform7/Chapter 19/Spatial Map.w"
void save_component_positions(connected_submap *sub) {
instance *R;
LOOP_OVER_SUBMAP(R, sub)
PF_I(map, R)->saved_gridpos = Room_position(R);
}
void restore_component_positions(connected_submap *sub) {
instance *R;
LOOP_OVER_SUBMAP(R, sub)
set_room_position(R, PF_I(map, R)->saved_gridpos);
}
#line 1891 "inform7/Chapter 19/Spatial Map.w"
void cool_submap(connected_submap *sub) {
int initial_heat = 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;
save_component_positions(sub);
LOOP_OVER_SUBMAP(R, sub) cool_component_from(sub, R);
find_submap_heat(sub);
if (sub->heat == 0) break;
if (sub->heat >= heat_before_round) {
restore_component_positions(sub);
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 19/Spatial Map.w"
void 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 19/Spatial Map.w"
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
exit_heats[i] = find_exit_heat(R, i);
exit_rooms[i] = read_smap(R, i);
}
}
#line 1935 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 1979 "inform7/Chapter 19/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) {
cool_exit(R, i);
exit_heats[i] = 0; exits_cooled++;
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 19/Spatial Map.w"
;
}
#line 2009 "inform7/Chapter 19/Spatial Map.w"
instance *saved_to; vector Saved_position;
void undo_cool_exit(void) {
move_room_to(saved_to, Saved_position);
LOGIF(SPATIAL_MAP_WORKINGS, "Undoing move of $O\n", saved_to);
}
void cool_exit(instance *R, int exit) {
instance *to = read_smap(R, exit);
saved_to = to; Saved_position = Room_position(to);
vector D = Plugins__Map__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;
move_room_to(saved_to, N);
LOGIF(SPATIAL_MAP_WORKINGS, "Moving $O %s from $O: now at (%d,%d,%d)\n",
to, Plugins__Map__find_icon_label(exit), R, N.x, N.y, N.z);
}
#line 2045 "inform7/Chapter 19/Spatial Map.w"
void quench_submap(connected_submap *sub, instance *avoid1, instance *avoid2) {
int initial_heat = 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 (find_exit_heat(R, i) > 0)
{
#line 2073 "inform7/Chapter 19/Spatial Map.w"
instance *T = 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, Plugins__Map__find_icon_label(i), T);
cool_exit(R, i);
int h = find_submap_heat(sub);
if (h >= heat) {
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 19/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 19/Spatial Map.w"
void diffuse_submap(connected_submap *sub) {
int initial_heat = 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 = read_smap(R, i);
if (T)
{
#line 2134 "inform7/Chapter 19/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, Plugins__Map__find_icon_label(i), T, L+1);
LOG_INDENT;
save_component_positions(sub);
vector O = Room_position(R);
PF_I(map, R)->exit_lengths[i] = L+1;
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;
diffuse_across(R, T);
LOOP_OVER_SUBMAP(S, sub)
if ((PF_I(map, S)->zone == 2) && (S != R))
translate_room(S, D);
find_submap_heat(sub);
if (sub->heat >= heat) {
restore_component_positions(sub);
PF_I(map, R)->exit_lengths[i] = L;
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 19/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 19/Spatial Map.w"
void diffuse_across(instance *at, instance *avoiding) {
PF_I(map, at)->zone = 2;
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = read_slock(at, i);
if ((T) && (PF_I(map, T)->zone == 1)) diffuse_across(T, avoiding);
}
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = read_smap(at, i);
if ((T) && (PF_I(map, T)->zone == 1) && (T != avoiding) &&
(find_exit_heat(at, i) == 0))
diffuse_across(T, avoiding);
}
}
#line 2203 "inform7/Chapter 19/Spatial Map.w"
void radiate_submap(connected_submap *sub) {
int initial_heat = 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 = read_smap(R, i);
if (T) {
if (exit_aligned(R, i) == FALSE)
{
#line 2242 "inform7/Chapter 19/Spatial Map.w"
LOGIF(SPATIAL_MAP_WORKINGS, "Map misaligned on $O %s to $O.\n",
R, Plugins__Map__find_icon_label(i), T);
LOG_INDENT;
int j;
vector O = Room_position(R);
LOOP_OVER_LATTICE_DIRECTIONS(j) {
vector E = Plugins__Map__direction_as_vector(j);
int L;
for (L = 1; L <= MAX_RADIATION_DISTANCE; L++) {
vector D = Geometry__vec_scale(L, E);
set_room_position(R, Geometry__vec_plus(O, D));
if (exit_aligned(R, i))
{
#line 2264 "inform7/Chapter 19/Spatial Map.w"
LOGIF(SPATIAL_MAP_WORKINGS, "Aligned at offset %d, %d, %d\n", D.x, D.y, D.z);
save_component_positions(sub);
instance *S;
LOOP_OVER_SUBMAP(S, sub) PF_I(map, S)->zone = 1;
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);
translate_room(S, D);
}
find_submap_heat(sub);
if (sub->heat >= heat) {
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 19/Spatial Map.w"
;
}
set_room_position(R, O);
}
Escape: ;
LOG_OUTDENT;
}
#line 2219 "inform7/Chapter 19/Spatial Map.w"
;
}
}
}
LOG_OUTDENT;
}
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 19/Spatial Map.w"
void radiate_across(instance *at, instance *avoiding, int not_this_way) {
PF_I(map, at)->zone = 2;
int i, not_this_way_either = Plugins__Map__opposite(not_this_way);
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = read_slock(at, i);
if ((T) && (PF_I(map, T)->zone == 1))
radiate_across(T, avoiding, not_this_way);
}
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = read_smap(at, i);
if ((T) && (PF_I(map, T)->zone == 1) && (T != avoiding) &&
(i != not_this_way) && (i != not_this_way_either))
radiate_across(T, avoiding, not_this_way);
}
}
#line 2327 "inform7/Chapter 19/Spatial Map.w"
void explode_submap(connected_submap *sub) {
int initial_heat = 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 (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 (occupied_in_submap(sub, V) == 0) {
move_room_to(R, V);
int h = find_submap_heat(sub);
if (h < coldest) { Coldest = V; coldest = h; }
}
}
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;
}
}
}
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 19/Spatial Map.w"
int 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 = Plugins__Regions__enclosing(R1);
instance *reg2 = Plugins__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 19/Spatial Map.w"
int component_is_adjoining(connected_submap *sub) {
if (no_links_to_placed_components(sub) > 0) return TRUE;
return FALSE;
}
int component_is_isolated(connected_submap *sub) {
if (no_links_to_other_components(sub) == 0) return TRUE;
return FALSE;
}
#line 2562 "inform7/Chapter 19/Spatial Map.w"
int 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 (occupied_in_submap(other, Room_position(R)))
return FUSION_POINT;
}
int heat = find_cross_component_heat(sub);
if (heat >= FUSION_POINT) heat = FUSION_POINT - 1;
return heat;
}
#line 2579 "inform7/Chapter 19/Spatial Map.w"
int find_cross_component_heat(connected_submap *sub) {
int heat = 0;
cross_component_links(sub, NULL, NULL, &heat, TRUE);
return heat;
}
void find_link_to_placed_components(connected_submap *sub,
instance **outer, instance **inner) {
cross_component_links(sub, outer, inner, NULL, TRUE);
}
int no_links_to_placed_components(connected_submap *sub) {
return cross_component_links(sub, NULL, NULL, NULL, TRUE);
}
int no_links_to_other_components(connected_submap *sub) {
return cross_component_links(sub, NULL, NULL, NULL, FALSE);
}
#line 2607 "inform7/Chapter 19/Spatial Map.w"
int 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 = 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 = heat_sum(*heat, 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 = 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 = heat_sum(*heat, find_cross_link_heat(S, R2, d));
}
}
}
}
if (no_links == 0)
{
#line 2649 "inform7/Chapter 19/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 = Plugins__Regions__enclosing(R);
if (reg) {
instance *S, *closest_S = NULL;
int closest = 0;
LOOP_OVER_ROOMS(S)
if ((S != R) && (Plugins__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 = heat_sum(*heat, find_cross_link_heat(closest_S, R, 3));
}
}
}
}
}
#line 2639 "inform7/Chapter 19/Spatial Map.w"
;
return no_links;
}
#line 2682 "inform7/Chapter 19/Spatial Map.w"
int find_cross_link_heat(instance *R, instance *S, int dir) {
if ((R == NULL) || (S == NULL)) internal_error("bad room distance");
return component_metric(Room_position(R), Room_position(S), dir);
}
int 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 19/Spatial Map.w"
void 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 19/Spatial Map.w"
if ((Data__Instances__of_kind(R, K_direction)) &&
(PF_I(map, R)->direction_index >= 12)) {
int w1 = -1, w2 = -1;
Data__Instances__get_name(R, &w1, &w2, FALSE);
int ow1 = -1, ow2 = -1;
Data__Instances__get_name(Plugins__Map__get_value_of_opposite_property(R), &ow1, &ow2, FALSE);
LOG("$c is a direction. The opposite of $c is $c.\n", w1, w2, w1, w2, ow1, ow2);
}
if (Data__Instances__of_kind(R, K_region)) {
int w1 = -1, w2 = -1;
Data__Instances__get_name(R, &w1, &w2, FALSE);
LOG("$c is a region.\n", w1, w2);
}
if (Data__Instances__of_kind(R, K_door)) {
int w1 = -1, w2 = -1;
Data__Instances__get_name(R, &w1, &w2, FALSE);
LOG("$c is a door.\n", w1, w2);
specification *S = World__Inferences__get_prop_state(
Data__Instances__as_subject(R), P_other_side);
instance *X = Specifications__Values__instance_of_CONSTANT_object_if_any(S);
if (X) {
int x1 = -1, x2 = -1;
Data__Instances__get_name(X, &x1, &x2, FALSE);
LOG("The other side of $c is $c.\n", w1, w2, x1, x2);
}
}
}
#line 2753 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 2795 "inform7/Chapter 19/Spatial Map.w"
if (Data__Instances__of_kind(R, K_room)) {
int w1 = -1, w2 = -1;
Data__Instances__get_name(R, &w1, &w2, FALSE);
LOG("$c is a room.\n", w1, w2);
instance *reg = Plugins__Regions__enclosing(R);
if (reg) {
int rw1 = -1, rw2 = -1;
Data__Instances__get_name(reg, &rw1, &rw2, FALSE);
if (PF_I(map, reg)->zone == 1) {
LOG("$c is a region.\n", rw1, rw2);
PF_I(map, reg)->zone = 0;
}
LOG("$c is in $c.\n", w1, w2, rw1, rw2);
}
instance *start = Plugins__Player__get_start_room();
if (R == start) {
LOG("The player is in $c.\n", w1, w2);
}
}
}
#line 2754 "inform7/Chapter 19/Spatial Map.w"
;
PF_I(map, R)->zone = 0;
}
{
#line 2818 "inform7/Chapter 19/Spatial Map.w"
instance *R;
LOOP_OVER_ROOMS(R) {
int w1 = -1, w2 = -1;
Data__Instances__get_name(R, &w1, &w2, FALSE);
int i;
LOOP_OVER_STORY_DIRECTIONS(i) {
instance *D = NULL;
instance *S = Plugins__Map__room_exit(R, i, &D);
if ((S) || (D)) {
int ow1 = -1, ow2 = -1;
if (D) Data__Instances__get_name(D, &ow1, &ow2, FALSE);
else Data__Instances__get_name(S, &ow1, &ow2, FALSE);
if (i < 12) {
char *n = usual_Inform_direction_name(i);
int opp = Plugins__Map__opposite(i);
LOG("$c is %s of $c.\n", ow1, ow2, n, w1, w2);
if ((S) && (Plugins__Map__room_exit(S, opp, NULL) == NULL))
LOG("%s of $c is nowhere.\n",
usual_Inform_direction_name(opp), ow1, ow2);
} else {
instance *dir;
LOOP_OVER_INSTANCES(dir, K_direction)
if (PF_I(map, dir)->direction_index == i) {
int dw1 = -1, dw2 = -1;
Data__Instances__get_name(dir, &dw1, &dw2, FALSE);
LOG("$c is $W of $c.\n", ow1, ow2, dw1, dw2, w1, w2);
instance *opp = Plugins__Map__get_value_of_opposite_property(dir);
int od = PF_I(map, opp)->direction_index;
if ((S) && (Plugins__Map__room_exit(S, od, NULL) == NULL)) {
int opw1 = -1, opw2 = -1;
Data__Instances__get_name(dir, &opw1, &opw2, FALSE);
LOG("$W of $c is nowhere.\n", opw1, opw2, ow1, ow2);
}
}
}
}
}
}
}
#line 2757 "inform7/Chapter 19/Spatial Map.w"
;
{
#line 2860 "inform7/Chapter 19/Spatial Map.w"
parse_node *p = NULL, *prevp = NULL;
for (prevp=NULL, TREE_START(p); p; prevp=p, TREE_NEXT(p))
if ((Parser__Nodes__type(p) == SENTENCE_NT)
&& (p->down)
&& (Parser__Nodes__int_annotation(p->down, verb_id_ANNOT) == MAP_PARAMETER_VB)
&& (p->down->next) && (p->down->next))
LOG("\nIndex map with $c.\n", p->down->next->word_ref1,
p->down->next->word_ref2);
}
#line 2758 "inform7/Chapter 19/Spatial Map.w"
;
LOG("\n[Precis complete.]\n\n");
}
#line 2872 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__index_room_connections(instance *R) {
int rw1 = -1, rw2 = -1; /* name of the origin room */
Data__Instances__get_name(R, &rw1, &rw2, FALSE);
instance *dir;
LOOP_OVER_INSTANCES(dir, K_direction) {
int i = PF_I(map, dir)->direction_index;
instance *opp = Plugins__Map__get_value_of_opposite_property(dir);
int od = opp?(PF_I(map, opp)->direction_index):(-1);
instance *D = NULL;
instance *S = Plugins__Map__room_exit(R, i, &D);
if ((S) || (D)) {
Formats__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);
Data__Instances__index_name(dir);
INDEX(" to ");
if (S) {
Data__Instances__index_name(S);
if (D) {
INDEX(" via ");
Data__Instances__index_name(D);
}
} else {
Data__Instances__index_name(D);
INDEX(" (a door)");
}
if (S) {
instance *B = opp?(Plugins__Map__room_exit(S, od, NULL)):NULL;
if (B == NULL) {
INDEX(" (but ");
Data__Instances__index_name(opp);
INDEX(" from ");
Data__Instances__index_name(S);
INDEX(" is nowhere)");
} else if (B != R) {
INDEX(" (but ");
Data__Instances__index_name(opp);
INDEX(" from ");
Data__Instances__index_name(S);
INDEX(" is ");
Data__Instances__index_name(B);
INDEX(")");
}
}
parse_node *at = PF_I(map, R)->exits_set_at[i];
if (at) Index__link(at->word_ref1);
INDEX("</p>");
}
}
int k = 0;
LOOP_OVER_INSTANCES(dir, K_direction) {
int i = PF_I(map, dir)->direction_index;
if (Plugins__Map__room_exit(R, i, NULL)) continue;
int dw1 = -1, dw2 = -1; /* name of the direction */
Data__Instances__get_name(dir, &dw1, &dw2, FALSE);
k++;
if (k == 1) {
Formats__HTML__open_para(ifl, 1, "hanging");
INDEX("<i>add:</i> ");
} else {
INDEX("; ");
}
TEMPORARY_STREAM;
char *p = Text__word_raw_text(dw1);
int j;
for (j=0; p[j]; j++) {
if (j==0) STREAM_WRITE(TEMP, "%c", Platform__toupper(p[j]));
else STREAM_WRITE(TEMP, "%c", p[j]);
}
if (dw1 < dw2) {
STREAM_WRITE(TEMP, " ");
Text__print_raw_text_to_stream(dw1+1, dw2, TEMP);
}
STREAM_WRITE(TEMP, " from ");
if (rw1 >= 0) Text__print_raw_text_to_stream(rw1, rw2, TEMP);
else STREAM_WRITE(TEMP, "here");
STREAM_WRITE(TEMP, " is .[=0x000A=]");
Formats__HTML__Javascript__paste(ifl, -1, -1, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
INDEX("&nbsp;");
Text__print_raw_text_to_stream(dw1, dw2, ifl);
}
if (k>0) INDEX("</p>");
}
#line 2964 "inform7/Chapter 19/Spatial Map.w"
void Plugins__Map__log_spatial_layout(void) {
Plugins__Map__establish_benchmark_room();
Plugins__Map__traverse_for_map_parameters(1);
Plugins__Map__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) {
int w1, w2;
Data__Instances__get_name(R, &w1, &w2, FALSE);
if (R == benchmark_room) LOG("Benchmark: ");
LOG("$W: %d, %d, %d\n", w1, w2,
Room_position(R).x,
Room_position(R).y,
Room_position(R).z);
}
}
}
#line 29 "inform7/Chapter 19/HTML Map.w"
instance **room_grid = NULL;
int *icon_grid = NULL, *exit_grid = NULL;
void calculate_map_grid(void) {
{
#line 42 "inform7/Chapter 19/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 19/HTML Map.w"
;
{
#line 60 "inform7/Chapter 19/HTML Map.w"
instance *R;
LOOP_OVER_ROOMS(R)
room_grid[ROOM_GRID_POS(Room_position(R))] = R;
}
#line 34 "inform7/Chapter 19/HTML Map.w"
;
{
#line 67 "inform7/Chapter 19/HTML Map.w"
instance *R;
LOOP_OVER_ROOMS(R) {
int exit;
LOOP_OVER_STORY_DIRECTIONS(exit)
if (Plugins__Map__direction_is_mappable(exit)) {
instance *D = NULL; /* door which the exit passes through, if it does */
instance *T = Plugins__Map__room_exit(R, exit, &D); /* target at the other end */
if ((T) || (D))
{
#line 114 "inform7/Chapter 19/HTML Map.w"
int i1, i2;
Plugins__Map__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 = Plugins__Map__direction_as_vector(exit);
if ((Geometry__vec_eq(E, Zero_vector) == FALSE) &&
(Plugins__Map__direction_is_lateral(exit))) {
{
#line 139 "inform7/Chapter 19/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 19/HTML Map.w"
;
{
#line 157 "inform7/Chapter 19/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 19/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 19/HTML Map.w"
;
}
}
}
#line 35 "inform7/Chapter 19/HTML Map.w"
;
{
#line 166 "inform7/Chapter 19/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);
correct_pair(P, SW_vector, 0, 4, 4, 0);
correct_pair(P, W_vector, 0, 2, 4, 2);
correct_pair(P, NW_vector, 0, 0, 4, 4);
correct_pair(P, S_vector, 2, 4, 2, 0);
correct_pair(P, N_vector, 2, 0, 2, 4);
correct_pair(P, SE_vector, 4, 4, 0, 0);
correct_pair(P, E_vector, 4, 2, 0, 2);
correct_pair(P, NE_vector, 4, 0, 0, 4);
}
}
#line 36 "inform7/Chapter 19/HTML Map.w"
;
}
#line 197 "inform7/Chapter 19/HTML Map.w"
void 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 19/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 19/HTML Map.w"
else
{
#line 262 "inform7/Chapter 19/HTML Map.w"
vector N = P;
if (D.x < 0) N.x--;
if (D.y < 0) N.y--;
correct_diagonal(N, TRUE);
correct_diagonal(N, FALSE);
}
#line 207 "inform7/Chapter 19/HTML Map.w"
;
if (from & ALIGNED_MAPBIT)
{
#line 221 "inform7/Chapter 19/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 19/HTML Map.w"
;
}
#line 274 "inform7/Chapter 19/HTML Map.w"
void 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 19/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 19/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 19/HTML Map.w"
else
{
#line 322 "inform7/Chapter 19/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 19/HTML Map.w"
;
}
}
}
#line 290 "inform7/Chapter 19/HTML Map.w"
;
{
#line 330 "inform7/Chapter 19/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 19/HTML Map.w"
;
}
#line 346 "inform7/Chapter 19/HTML Map.w"
int map_tables_begun = 2;
void begin_variable_width_table(void) {
{
#line 378 "inform7/Chapter 19/HTML Map.w"
int i;
INDEX("\n");
for (i=0; i<map_tables_begun; i++) INDEX(" ");
}
#line 348 "inform7/Chapter 19/HTML Map.w"
;
map_tables_begun++;
Formats__HTML__begin_html_table(ifl, NULL, FALSE, 0, 0, 0, 0, 0);
}
void begin_map_table(int width, int height) {
{
#line 378 "inform7/Chapter 19/HTML Map.w"
int i;
INDEX("\n");
for (i=0; i<map_tables_begun; i++) INDEX(" ");
}
#line 354 "inform7/Chapter 19/HTML Map.w"
;
map_tables_begun++;
Formats__HTML__begin_html_table(ifl, NULL, FALSE, 0, 0, 0, height, width);
}
void begin_variable_width_table_with_background(char *bg_image) {
{
#line 378 "inform7/Chapter 19/HTML Map.w"
int i;
INDEX("\n");
for (i=0; i<map_tables_begun; i++) INDEX(" ");
}
#line 360 "inform7/Chapter 19/HTML Map.w"
;
map_tables_begun++;
Formats__HTML__begin_html_table_bg(ifl, NULL, FALSE, 0, 0, 0, 0, 0, bg_image);
}
#line 368 "inform7/Chapter 19/HTML Map.w"
void end_map_table(void) {
map_tables_begun--;
{
#line 378 "inform7/Chapter 19/HTML Map.w"
int i;
INDEX("\n");
for (i=0; i<map_tables_begun; i++) INDEX(" ");
}
#line 370 "inform7/Chapter 19/HTML Map.w"
;
Formats__HTML__end_html_table(ifl);
INDEX("\n");
}
#line 388 "inform7/Chapter 19/HTML Map.w"
void plot_map_icon(char *icon_name) {
INDEX("<img border=0 src=inform:/map_icons/%s.png>", icon_name);
}
void 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 19/HTML Map.w"
void Plugins__Map__render_map_as_HTML(void) {
calculate_map_grid();
{
#line 425 "inform7/Chapter 19/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 =
Formats__HTML__translate_colour_name(
some_map_colours[(regc++) % NO_REGION_COLOURS]);
}
#line 406 "inform7/Chapter 19/HTML Map.w"
;
{
#line 445 "inform7/Chapter 19/HTML Map.w"
char *default_room_col = Formats__HTML__translate_colour_name("Light Grey");
instance *R;
LOOP_OVER_ROOMS(R)
if (PF_I(map, R)->world_index_colour == NULL) {
instance *reg = Plugins__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 19/HTML Map.w"
;
if (Data__Instances__count(K_room) >= 2) {
INDEX("\n\n<!--WORLD INDEX MAP BEGINS-->\n<p>\n");
{
#line 459 "inform7/Chapter 19/HTML Map.w"
begin_variable_width_table();
int z;
for (z=Universe.corner1.z; z>=Universe.corner0.z; z--) {
{
#line 472 "inform7/Chapter 19/HTML Map.w"
char *level_rubric = "Map"; int par = 0;
Plugins__Map__devise_level_rubric(z, &level_rubric, &par);
INDEX("<tr><td>");
int rounding = 0;
if (z == Universe.corner1.z) rounding = ROUND_BOX_TOP;
Formats__HTML__open_coloured_box(ifl, "e0e0e0", rounding);
INDEX("<i>"); INDEX(level_rubric, par); INDEX("</i>");
Formats__HTML__close_coloured_box(ifl, "e0e0e0", rounding);
INDEX("</td></tr>");
}
#line 462 "inform7/Chapter 19/HTML Map.w"
;
{
#line 485 "inform7/Chapter 19/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>");
plot_map_level(Universe.corner0.x, Universe.corner1.x, y_min, y_max, z, 1);
INDEX("</td></tr>");
}
#line 463 "inform7/Chapter 19/HTML Map.w"
;
}
{
#line 503 "inform7/Chapter 19/HTML Map.w"
INDEX("<tr><td>");
Formats__HTML__open_coloured_box(ifl, "e0e0e0", ROUND_BOX_BOTTOM);
Formats__HTML__close_coloured_box(ifl, "e0e0e0", ROUND_BOX_BOTTOM);
INDEX("</td></tr>");
}
#line 465 "inform7/Chapter 19/HTML Map.w"
;
end_map_table();
{
#line 511 "inform7/Chapter 19/HTML Map.w"
instance *D; int k = 0;
LOOP_OVER_INSTANCES(D, K_direction) {
instance *A = Plugins__Map__mapped_as_if(D);
if (A) {
k++;
if (k == 1) {
INDEX("<p><i>Mapping ");
} else INDEX("; ");
int dw1 = -1, dw2 = -1; /* name of the direction */
Data__Instances__get_name(D, &dw1, &dw2, FALSE);
int aw1 = -1, aw2 = -1; /* name of the as-direction */
Data__Instances__get_name(A, &aw1, &aw2, FALSE);
Text__print_raw_text_to_stream(dw1, dw2, ifl);
INDEX(" as ");
Text__print_raw_text_to_stream(aw1, aw2, ifl);
}
}
if (k > 0) INDEX("</i></p>");
}
#line 467 "inform7/Chapter 19/HTML Map.w"
;
}
#line 411 "inform7/Chapter 19/HTML Map.w"
;
INDEX("</p>\n<!--WORLD INDEX MAP ENDS-->\n");
}
}
#line 533 "inform7/Chapter 19/HTML Map.w"
void Plugins__Map__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 574 "inform7/Chapter 19/HTML Map.w"
void Plugins__Map__render_single_room_as_HTML(instance *R) {
INDEX("\n\n");
nametag *nt = Data__Instances__get_nametag(R);
Index__anchor(Data__Nametags__identifier(nt));
INDEX("<a name=wo_%d>", R->allocation_id);
Formats__HTML__begin_plain_html_table(ifl);
Formats__HTML__first_html_column(ifl, 0);
vector P = Room_position(R);
plot_map_level(P.x, P.x, P.y, P.y, P.z, 2);
Formats__HTML__next_html_column(ifl, 0);
INDEX("&nbsp;");
Formats__HTML__next_html_column(ifl, 0);
Data__Objects__index(R, NULL, 1, FALSE);
Formats__HTML__end_html_row(ifl);
Formats__HTML__end_html_table(ifl);
INDEX("<p>");
}
#line 599 "inform7/Chapter 19/HTML Map.w"
void 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");
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 656 "inform7/Chapter 19/HTML Map.w"
end_map_table();
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>");
begin_map_table(MAP_CELL_SIZE, MAP_DISLOCATION_HEIGHT);
INDEX("<tr>");
INDEX("<td>");
INDEX("</td>");
INDEX("</tr>");
end_map_table();
INDEX("</td>");
}
INDEX("</tr>");
end_map_table();
begin_variable_width_table_with_background("grid.png");
}
#line 617 "inform7/Chapter 19/HTML Map.w"
;
}
continue;
}
just_dislocated = FALSE;
{
#line 678 "inform7/Chapter 19/HTML Map.w"
{
#line 685 "inform7/Chapter 19/HTML Map.w"
INDEX("<tr>");
if (with_numbering)
{
#line 831 "inform7/Chapter 19/HTML Map.w"
INDEX("<td>");
begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
INDEX("</td>");
INDEX("</tr>");
end_map_table();
INDEX("</td>");
}
#line 686 "inform7/Chapter 19/HTML Map.w"
;
for (x=x0; x<=x1; x++)
{
#line 712 "inform7/Chapter 19/HTML Map.w"
vector P = Geometry__vec(x, y, z);
INDEX("<td>");
begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
plot_map_cell(pass, P, 0, 0, 2);
if (icon_grid[ICON_GRID_POS(P, 0, 0)] & CONNECTIVE_BITMAP)
plot_map_icon("s_dot"); else plot_map_icon("ns_spacer");
plot_map_cell(pass, P, 1, 0, 8);
plot_map_cell(pass, P, 2, 0, 0);
plot_map_cell(pass, P, 3, 0, -1);
if (icon_grid[ICON_GRID_POS(P, 4, 0)] & CONNECTIVE_BITMAP)
plot_map_icon("s_dot"); else plot_map_icon("ns_spacer");
plot_map_cell(pass, P, 4, 0, 1);
INDEX("</td>");
INDEX("</tr>");
end_map_table();
INDEX("</td>");
}
#line 687 "inform7/Chapter 19/HTML Map.w"
;
if (with_numbering)
{
#line 831 "inform7/Chapter 19/HTML Map.w"
INDEX("<td>");
begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
INDEX("</td>");
INDEX("</tr>");
end_map_table();
INDEX("</td>");
}
#line 688 "inform7/Chapter 19/HTML Map.w"
INDEX("</tr>");
}
#line 678 "inform7/Chapter 19/HTML Map.w"
;
{
#line 694 "inform7/Chapter 19/HTML Map.w"
INDEX("<tr>");
if (with_numbering)
{
#line 848 "inform7/Chapter 19/HTML Map.w"
INDEX("<td>");
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>");
end_map_table();
INDEX("</td>");
}
#line 695 "inform7/Chapter 19/HTML Map.w"
;
for (x=x0; x<=x1; x++)
{
#line 734 "inform7/Chapter 19/HTML Map.w"
vector P = Geometry__vec(x, y, z);
INDEX("<td>");
begin_map_table(MAP_CELL_SIZE, MAP_CELL_INNER_SIZE);
INDEX("<tr>");
INDEX("<td>");
begin_variable_width_table();
INDEX("<tr>");
INDEX("<td>");
if (icon_grid[ICON_GRID_POS(P, 0, 0)] & CONNECTIVE_BITMAP)
plot_map_icon("e_dot"); else plot_map_icon("ew_spacer");
INDEX("<br>");
plot_map_cell(pass, P, 0, 1, 11);
INDEX("<br>");
plot_map_cell(pass, P, 0, 2, 7);
INDEX("<br>");
plot_map_cell(pass, P, 0, 3, -1);
INDEX("<br>");
if (icon_grid[ICON_GRID_POS(P, 0, 4)] & CONNECTIVE_BITMAP)
plot_map_icon("e_dot"); else plot_map_icon("ew_spacer");
INDEX("</td>");
INDEX("</tr>");
end_map_table();
INDEX("</td>");
{
#line 788 "inform7/Chapter 19/HTML Map.w"
INDEX("<td>");
int bits = (icon_grid[ICON_GRID_POS(P, 2, 2)]) & LONGS_BITMAP;
if (bits == 0)
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");
plot_map_icon(icon_name);
}
INDEX("</td>");
}
#line 758 "inform7/Chapter 19/HTML Map.w"
;
INDEX("<td>");
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)
plot_map_icon("w_dot"); else plot_map_icon("ew_spacer");
INDEX("<br>");
plot_map_cell(pass, P, 4, 1, -1);
INDEX("<br>");
plot_map_cell(pass, P, 4, 2, 6);
INDEX("<br>");
plot_map_cell(pass, P, 4, 3, 10);
INDEX("<br>");
if (icon_grid[ICON_GRID_POS(P, 4, 4)] & CONNECTIVE_BITMAP)
plot_map_icon("w_dot"); else plot_map_icon("ew_spacer");
INDEX("</td>");
INDEX("</tr>");
end_map_table();
INDEX("</td>");
INDEX("</tr>");
end_map_table();
INDEX("</td>");
}
#line 696 "inform7/Chapter 19/HTML Map.w"
;
if (with_numbering)
{
#line 848 "inform7/Chapter 19/HTML Map.w"
INDEX("<td>");
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>");
end_map_table();
INDEX("</td>");
}
#line 697 "inform7/Chapter 19/HTML Map.w"
;
INDEX("</tr>");
}
#line 679 "inform7/Chapter 19/HTML Map.w"
;
{
#line 703 "inform7/Chapter 19/HTML Map.w"
INDEX("<tr>");
if (with_numbering)
{
#line 831 "inform7/Chapter 19/HTML Map.w"
INDEX("<td>");
begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
INDEX("</td>");
INDEX("</tr>");
end_map_table();
INDEX("</td>");
}
#line 704 "inform7/Chapter 19/HTML Map.w"
for (x=x0; x<=x1; x++)
{
#line 806 "inform7/Chapter 19/HTML Map.w"
vector P = Geometry__vec(x, y, z);
INDEX("<td>");
begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
plot_map_cell(pass, P, 0, 4, 5);
if (icon_grid[ICON_GRID_POS(P, 0, 4)] & CONNECTIVE_BITMAP)
plot_map_icon("n_dot"); else plot_map_icon("ns_spacer");
plot_map_cell(pass, P, 1, 4, -1);
plot_map_cell(pass, P, 2, 4, 3);
plot_map_cell(pass, P, 3, 4, 9);
if (icon_grid[ICON_GRID_POS(P, 4, 4)] & CONNECTIVE_BITMAP)
plot_map_icon("n_dot"); else plot_map_icon("ns_spacer");
plot_map_cell(pass, P, 4, 4, 4);
INDEX("</td>");
INDEX("</tr>");
end_map_table();
INDEX("</td>");
}
#line 705 "inform7/Chapter 19/HTML Map.w"
;
if (with_numbering)
{
#line 831 "inform7/Chapter 19/HTML Map.w"
INDEX("<td>");
begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
INDEX("</td>");
INDEX("</tr>");
end_map_table();
INDEX("</td>");
}
#line 706 "inform7/Chapter 19/HTML Map.w"
INDEX("</tr>");
}
#line 680 "inform7/Chapter 19/HTML Map.w"
;
}
#line 622 "inform7/Chapter 19/HTML Map.w"
;
}
end_map_table();
}
#line 871 "inform7/Chapter 19/HTML Map.w"
void 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 881 "inform7/Chapter 19/HTML Map.w"
if ((i1 == 1) || (i1 == 3)) plot_map_icon("blank_ns");
else {
if ((i2 == 1) || (i2 == 3)) plot_map_icon("blank_ew");
else plot_map_icon("blank_square");
}
}
#line 874 "inform7/Chapter 19/HTML Map.w"
else
{
#line 890 "inform7/Chapter 19/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 = Plugins__Map__find_icon_label(exit);
if (clue == NULL) clue = Plugins__Map__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 916 "inform7/Chapter 19/HTML Map.w"
instance *D = NULL;
instance *I3 = Plugins__Map__room_exit(room_grid[ROOM_GRID_POS(P)], exit, &D);
if ((I3) || (D)) {
STREAM_WRITE(TEMP, "title=\"");
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (Plugins__Counting__instance_count(I, K_direction) == exit) {
Data__Instances__write_name_for_index(TEMP, I);
break;
}
if (D) {
if (I3 == NULL) STREAM_WRITE(TEMP, " exit blocked by ");
else STREAM_WRITE(TEMP, " through ");
Data__Instances__write_name_for_index(TEMP, D);
}
if (I3) {
STREAM_WRITE(TEMP, " to ");
Data__Instances__write_name_for_index(TEMP, I3);
}
STREAM_WRITE(TEMP, "\"");
tool_tip = STREAM_TEXT(TEMP);
}
}
#line 908 "inform7/Chapter 19/HTML Map.w"
;
if (tool_tip) plot_map_icon_with_tip(icon_name, tool_tip);
else plot_map_icon(icon_name);
CLOSE_TEMPORARY_STREAM;
}
#line 875 "inform7/Chapter 19/HTML Map.w"
;
}
#line 950 "inform7/Chapter 19/HTML Map.w"
void 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=\"");
Data__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 976 "inform7/Chapter 19/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 1007 "inform7/Chapter 19/HTML Map.w"
int i;
for (i=0; i<ABBREV_ROOMS_TO+1; i++) abbrev[i] = 0;
int w1, w2;
Data__Instances__get_name(I, &w1, &w2, FALSE);
if (w1 >= 0) {
int c = 0;
for (i=w1; i<=w2; i++) {
if ((i > w1) && (i < w2) && (parse_nt_against_word_range(map_name_abbreviation_omission_words_NTM, i, i, NULL, NULL))) continue;
char *p = Text__word_raw_text(i);
if (c < ABBREV_ROOMS_TO) abbrev[c++] = Platform__toupper(p[0]);
}
for (i=w1; i<=w2; i++) {
if ((i > w1) && (i < w2) && (parse_nt_against_word_range(map_name_abbreviation_omission_words_NTM, i, i, NULL, NULL))) continue;
char *p = Text__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 981 "inform7/Chapter 19/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++) Formats__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 966 "inform7/Chapter 19/HTML Map.w"
;
INDEX("</font></td></tr></table>\n");
}
}
#line 999 "inform7/Chapter 19/HTML Map.w"
int map_name_abbreviation_omission_words_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 1003 "inform7/Chapter 19/HTML Map.w"
#line 1037 "inform7/Chapter 19/HTML Map.w"
void Plugins__Map__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);
Data__Instances__index_name(Reg); INDEX(" region");
if (at) Index__link(at->word_ref1);
INDEX("&nbsp;</font></td></tr></table>\n");
}
#line 1052 "inform7/Chapter 19/HTML Map.w"
void Plugins__Map__add_region_key(void) {
instance *reg; int count = 0;
LOOP_OVER_INSTANCES(reg, K_region)
count += add_key_for(reg);
if (count > 0) count += add_key_for(NULL);
if (count > 0) INDEX("<hr>");
}
int add_key_for(instance *reg) {
int count = 0;
instance *R;
LOOP_OVER_ROOMS(R) {
if (Plugins__Regions__enclosing(R) == reg) {
if (count++ == 0) {
{
#line 1082 "inform7/Chapter 19/HTML Map.w"
INDEX("<p>");
Formats__HTML__begin_plain_html_table(ifl);
INDEX("<tr><td width=\"40\" valign=\"middle\" align=\"left\">");
index_room_square(R, 1);
INDEX("</td><td valign=\"middle\" align=\"left\">");
INDEX("<font %s>", DEFAULT_HTML_FONT);
INDEX("<b>");
int w1, w2;
Data__Instances__get_name(reg, &w1, &w2, FALSE);
if (reg) Text__print_raw_text_to_stream(w1, w2, ifl);
else INDEX("<i>Not in any region</i>");
INDEX("</b>: ");
}
#line 1066 "inform7/Chapter 19/HTML Map.w"
;
} else {
INDEX(", ");
}
int w1, w2;
Data__Instances__get_name(R, &w1, &w2, FALSE);
Text__print_raw_text_to_stream(w1, w2, ifl);
}
}
if (count > 0)
{
#line 1098 "inform7/Chapter 19/HTML Map.w"
Formats__HTML__end_html_row(ifl);
Formats__HTML__end_html_table(ifl);
INDEX("</p>");
}
#line 1075 "inform7/Chapter 19/HTML Map.w"
;
return count;
}
#line 158 "inform7/Chapter 19/EPS Map.w"
int get_map_variable_index(char *name) {
int s = 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 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 19/EPS Map.w"
void Plugins__Map__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 19/EPS Map.w"
void put_mp(char *name, map_parameter_scope *scope, instance *scope_I,
kind *scope_k, char *put_string, int put_integer) {
if (scope_I) {
if (Plugins__Spatial__object_is_a_room(scope_I))
scope = scope_for_single_room(scope_I);
else if (Plugins__Regions__object_is_a_region(scope_I)) {
instance *rm;
LOOP_OVER_INSTANCES(rm, K_room)
if (obj_in_region(rm, scope_I))
put_mp(name, NULL, rm, NULL, put_string, put_integer);
return;
} else return;
}
if (scope_k) {
instance *I;
LOOP_OVER_INSTANCES(I, scope_k)
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) put_string_mp(name, scope, put_string);
else put_int_mp(name, scope, put_integer);
}
map_parameter_scope *scope_for_single_room(instance *rm) {
return &(PF_I(map, rm)->local_map_parameters);
}
int obj_in_region(instance *I, instance *reg) {
if ((I == NULL) || (reg == NULL)) return FALSE;
if (Plugins__Regions__enclosing(I) == reg) return TRUE;
return obj_in_region(Plugins__Regions__enclosing(I), reg);
}
#line 242 "inform7/Chapter 19/EPS Map.w"
char *get_string_mp(char *name, map_parameter_scope *scope) {
int s = 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 get_string_mp("font", NULL);
return p;
}
void put_string_mp(char *name, map_parameter_scope *scope, char *val) {
int s = 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 19/EPS Map.w"
int get_int_mp(char *name, map_parameter_scope *scope) {
int s = 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 put_int_mp(char *name, map_parameter_scope *scope, int val) {
int s = 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 19/EPS Map.w"
void Plugins__Map__traverse_for_map_parameters(int pass) {
parse_node *p, *prevp;
if (pass == 1) Plugins__Map__initialise_page_directions();
for (prevp=NULL, TREE_START(p); p; prevp=p, TREE_NEXT(p)) {
if ((Parser__Nodes__type(p) == SENTENCE_NT)
&& (p->down)
&& (Parser__Nodes__int_annotation(p->down, verb_id_ANNOT) == MAP_PARAMETER_VB)
&& (p->down->next)) {
new_map_hint_sentence(pass, p->down->next);
}
}
}
#line 303 "inform7/Chapter 19/EPS Map.w"
int direction_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1]; if (Data__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 305 "inform7/Chapter 19/EPS Map.w"
#line 315 "inform7/Chapter 19/EPS Map.w"
int index_map_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 335 "inform7/Chapter 19/EPS Map.w"
*X = NO_IMW;
if (index_map_with_pass == 1) {
Problems__map_problem(_P_(C19MapDirectionClue),
index_map_with_p, "You can only say 'Index map with D mapped as E.' "
"when D and E are directions.");
}
}
#line 318 "inform7/Chapter 19/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 345 "inform7/Chapter 19/EPS Map.w"
*X = NO_IMW;
if (index_map_with_pass == 1) {
Problems__map_problem(_P_(C19MapPlacement),
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 320 "inform7/Chapter 19/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 355 "inform7/Chapter 19/EPS Map.w"
*X = NO_IMW;
if (index_map_with_pass == 1) {
Problems__map_problem(_P_(C19MapSettingTooLong),
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 322 "inform7/Chapter 19/EPS Map.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7:
{
#line 365 "inform7/Chapter 19/EPS Map.w"
*X = NO_IMW;
{
#line 703 "inform7/Chapter 19/EPS Map.w"
if (index_map_with_pass == 1) {
Problems__map_problem(_P_(C19MapSettingOfUnknown),
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 366 "inform7/Chapter 19/EPS Map.w"
;
}
#line 323 "inform7/Chapter 19/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 371 "inform7/Chapter 19/EPS Map.w"
*X = NO_IMW;
if (index_map_with_pass == 2) {
Problems__map_problem(_P_(C19MapHintUnknown),
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 325 "inform7/Chapter 19/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 326 "inform7/Chapter 19/EPS Map.w"
int map_positioning_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 331 "inform7/Chapter 19/EPS Map.w"
#line 387 "inform7/Chapter 19/EPS Map.w"
int map_setting_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 425 "inform7/Chapter 19/EPS Map.w"
*X = NO_IMW;
if (index_map_with_pass == 1) {
Problems__map_problem(_P_(C19MapSettingUnknown),
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 390 "inform7/Chapter 19/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 391 "inform7/Chapter 19/EPS Map.w"
int map_setting_scope_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 395 "inform7/Chapter 19/EPS Map.w"
int map_setting_scope_unarticled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 401 "inform7/Chapter 19/EPS Map.w"
#line 410 "inform7/Chapter 19/EPS Map.w"
int map_parameter_NTMR(int w1, int w2, int *X, void **XP) {
#line 411 "inform7/Chapter 19/EPS Map.w"
int i;
char *parameter_name = Text__word_text(w1);
if ((w1 == w2) &&
((i = get_map_variable_index_forgivingly(parameter_name))>=0)) {
*X = i;
*XP = parameter_name;
return TRUE;
}
return FALSE;
}
#line 439 "inform7/Chapter 19/EPS Map.w"
int map_setting_value_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = INT_MDT; msvalue_NTMV = R[1]; msword_NTMV = w1;;
#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 = w1;;
#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 = w1;;
#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 = w1; 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 = w1; /* 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 445 "inform7/Chapter 19/EPS Map.w"
int map_setting_boolean_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 449 "inform7/Chapter 19/EPS Map.w"
#line 456 "inform7/Chapter 19/EPS Map.w"
int map_offset_NTMR(int w1, int w2, int *X, void **XP) {
#line 457 "inform7/Chapter 19/EPS Map.w"
*X = parse_eps_map_offset(Text__word_text(w1));
return TRUE;
}
#line 466 "inform7/Chapter 19/EPS Map.w"
int map_rubric_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = RUBRIC_SIZE; rsize_NTMV = R[1]; edge_NTMV = map_rubric_NTM->range_result_w1[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 = map_rubric_NTM->range_result_w1[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 = map_rubric_NTM->range_result_w1[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 = map_rubric_NTM->range_result_w1[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 = map_rubric_NTM->range_result_w1[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 19/EPS Map.w"
#line 494 "inform7/Chapter 19/EPS Map.w"
void new_map_hint_sentence(int pass, parse_node *p) {
if (Parser__Nodes__type(p) == AND_NT) {
new_map_hint_sentence(pass, p->down);
new_map_hint_sentence(pass, p->down->next);
return;
}
current_sentence = p;
int w1 = p->word_ref1, w2 = p->word_ref2;
index_map_with_pass = pass;
index_map_with_p = p;
/* the following take effect on pass 1 */
int i;
parse_nt_against_word_range(index_map_sentence_subject_NTM, w1, w2, NULL, NULL);
switch (most_recent_result) {
case EPSFILE_IMW: if (pass == 1) write_EPS_format_map = TRUE;
break;
case MAPPED_AS_IMW:
{
#line 527 "inform7/Chapter 19/EPS Map.w"
if (pass == 1)
Plugins__Map__map_direction_as_if(instance_x_NTMV, instance_y_NTMV);
}
#line 511 "inform7/Chapter 19/EPS Map.w"
;
break;
case MAPPED_IMW:
{
#line 533 "inform7/Chapter 19/EPS Map.w"
if (Data__Instances__of_kind(instance_dir_NTMV, K_direction) == FALSE) {
if (pass == 1) Problems__map_problem(_P_(C19MapPlacementDirection),
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) || (Plugins__Spatial__object_is_a_room(I) == FALSE)) {
if (pass == 1) Problems__map_problem(_P_(C19MapFromNonRoom),
p, "The first-named thing must be a room (beware ambiguities!).");
return;
}
if ((I2 == NULL) || (Plugins__Spatial__object_is_a_room(I2) == FALSE)) {
if (pass == 1) Problems__map_problem(_P_(C19MapToNonRoom),
p, "The second-named thing must be a room (beware ambiguities!).");
return;
}
if (Plugins__Map__direction_is_lateral(exit) == FALSE) {
if (pass == 1) Problems__map_problem(_P_(C19MapNonLateral),
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) Plugins__Map__lock_exit_in_place(I, exit, I2);
}
#line 513 "inform7/Chapter 19/EPS Map.w"
;
break;
case SETTING_IMW:
{
#line 638 "inform7/Chapter 19/EPS Map.w"
int allow_on_pass_2 = FALSE;
map_parameter_scope *scope = NULL;
instance *scope_I = NULL;
kind *scope_k = NULL;
{
#line 651 "inform7/Chapter 19/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__map_problem(_P_(C19MapLevelMisnamed),
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__lt(scope_k, K_object) == FALSE) scope_k = NULL;
if ((scope_k) &&
((Kinds__le(scope_k, K_room)) ||
(Kinds__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 ((Plugins__Spatial__object_is_a_room(instance_iscope_NTMV)) ||
(Plugins__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 703 "inform7/Chapter 19/EPS Map.w"
if (index_map_with_pass == 1) {
Problems__map_problem(_P_(C19MapSettingOfUnknown),
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 696 "inform7/Chapter 19/EPS Map.w"
;
return;
}
}
#line 642 "inform7/Chapter 19/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 714 "inform7/Chapter 19/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) {
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) {
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) {
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);
put_mp(parameter_name, scope, scope_I, scope_k, Text__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);
put_mp(parameter_name, scope, scope_I, scope_k, Text__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 = Formats__HTML__translate_colour_name(Text__word_text(wn));
if (col) {
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__map_problem_wanted_but(_P_(C19MapSettingTypeFailed),
p, i_wanted_a, wn);
}
#line 646 "inform7/Chapter 19/EPS Map.w"
;
}
#line 515 "inform7/Chapter 19/EPS Map.w"
;
break;
case RUBRIC_IMW:
if (pass == 2)
{
#line 566 "inform7/Chapter 19/EPS Map.w"
int r1, r2, rest1, rest2;
GET_RW(index_map_sentence_subject_NTM, 1, r1, r2);
GET_RW(index_map_sentence_subject_NTM, 2, rest1, rest2);
Text__dequote_word(r1);
rubric_holder *rh = CREATE(rubric_holder);
rh->annotation = Text__word_text(r1);
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;
i = rest1;
while (i <= rest2) {
if (parse_nt_against_word_range(map_rubric_NTM, i, rest2, 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 = Text__word_text(rfont_NTMV);
break;
case RUBRIC_COLOUR:
{
#line 606 "inform7/Chapter 19/EPS Map.w"
char *thec;
Text__dequote_word(rcol_NTMV);
thec = Formats__HTML__translate_colour_name(Text__word_text(rcol_NTMV));
if (thec == NULL) {
Problems__map_problem(_P_(C19MapUnknownColour), p, "There's no such map colour.");
return;
}
rh->colour = thec;
}
#line 590 "inform7/Chapter 19/EPS Map.w"
; break;
case RUBRIC_OFFSET:
case RUBRIC_POSITION:
{
#line 618 "inform7/Chapter 19/EPS Map.w"
if (roff_NTMV == ERRONEOUS_OFFSET_VALUE) {
Problems__map_problem(_P_(C19MapUnknownOffset), p, "There's no such offset.");
return;
}
rh->at_offset = roff_NTMV;
if (most_recent_result == RUBRIC_OFFSET) {
instance *I = Data__Instances__parse_object(i, w2);
i = rest2 + 1;
if (I == NULL) {
Problems__map_problem(_P_(C19MapUnknownOffsetBase),
p, "There's no such room to be offset from.");
return;
}
rh->offset_from = I;
}
}
#line 593 "inform7/Chapter 19/EPS Map.w"
; break;
}
} else {
Problems__map_problem(_P_(C19MapBadRubric),
p, "Unfortunately the details of that rubric seem to be "
"in error (a lame message, but an accurate one).");
break;
}
}
}
#line 519 "inform7/Chapter 19/EPS Map.w"
;
break;
}
}
#line 775 "inform7/Chapter 19/EPS Map.w"
int 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 802 "inform7/Chapter 19/EPS Map.w"
void Plugins__Map__render_map_as_EPS(void) {
{
#line 818 "inform7/Chapter 19/EPS Map.w"
EPS_map_level *main_eml = CREATE(EPS_map_level);
main_eml->width = get_int_mp("minimum-map-width", NULL);
main_eml->actual_height = 0;
main_eml->titling_point_size = get_int_mp("title-size", NULL);
strcpy(main_eml->titling, "Map");
main_eml->contains_titling = TRUE;
main_eml->contains_rooms = FALSE;
Plugins__Map__prepare_map_parameter_scope(&(main_eml->map_parameters));
put_string_mp("title", &(main_eml->map_parameters), main_eml->titling);
}
#line 803 "inform7/Chapter 19/EPS Map.w"
;
int z;
for (z=Universe.corner1.z; z>=Universe.corner0.z; z--)
{
#line 831 "inform7/Chapter 19/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;
Plugins__Map__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;
Plugins__Map__prepare_map_parameter_scope(&(eml->map_parameters));
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 806 "inform7/Chapter 19/EPS Map.w"
;
Plugins__Map__traverse_for_map_parameters(2);
if (changed_global_room_colour == FALSE)
{
#line 865 "inform7/Chapter 19/EPS Map.w"
instance *R;
LOOP_OVER_ROOMS(R)
put_string_mp("room-colour", &(PF_I(map, R)->local_map_parameters),
PF_I(map, R)->world_index_colour);
}
#line 810 "inform7/Chapter 19/EPS Map.w"
;
if (write_EPS_format_map)
{
#line 873 "inform7/Chapter 19/EPS Map.w"
STREAM EPS_struct; STREAM *EPS = &EPS_struct;
char *fn = Files__Filenames__build(EPSMAP_LEAFNAME);
fn = filename_of_epsfile;
if (STREAM_OPEN_TO_FILE(EPS, fn, ISO_ENC) == FALSE)
Problems__Fatal__issue2("Can't open EPS map file", fn);
EPS_compile_map(EPS);
STREAM_CLOSE(EPS);
}
#line 812 "inform7/Chapter 19/EPS Map.w"
;
}
#line 884 "inform7/Chapter 19/EPS Map.w"
void 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 = get_int_mp("border-size", NULL),
vskip = get_int_mp("vertical-spacing", NULL);
{
#line 927 "inform7/Chapter 19/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 = get_int_mp("grid-size", level_scope);
int p = get_int_mp("title-size", level_scope);
if (eml->contains_rooms) p = 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 889 "inform7/Chapter 19/EPS Map.w"
;
int bounding_box_width = blw+2*border, bounding_box_height = blh+2*border;
EPS_compile_header(OUT, bounding_box_width, bounding_box_height,
get_string_mp("title-font", NULL), get_int_mp("title-size", NULL));
if (get_int_mp("map-outline", NULL))
{
#line 952 "inform7/Chapter 19/EPS Map.w"
WRITE("newpath %% Ruled outline outer box of map\n");
EPS_compile_rectangular_path(OUT, border, border, border+blw, border+blh);
WRITE("stroke\n");
}
#line 896 "inform7/Chapter 19/EPS Map.w"
;
EPS_map_level *eml;
LOOP_OVER(eml, EPS_map_level) {
map_parameter_scope *level_scope = &(eml->map_parameters);
int mapunit = get_int_mp("grid-size", level_scope);
if (eml->contains_rooms == FALSE)
if (get_int_mp("map-outline", NULL))
{
#line 960 "inform7/Chapter 19/EPS Map.w"
WRITE("newpath %% Ruled horizontal line\n");
EPS_compile_horizontal_line_path(OUT, border, blw+border, eml->eps_origin);
WRITE("stroke\n");
}
#line 904 "inform7/Chapter 19/EPS Map.w"
;
if (eml->contains_titling)
{
#line 967 "inform7/Chapter 19/EPS Map.w"
int y = eml->eps_origin + vskip + eml->actual_height;
if (eml->contains_rooms) {
if (get_int_mp("monochrome", level_scope)) EPS_compile_set_greyscale(OUT, 0);
else EPS_compile_set_colour(OUT, get_string_mp("subtitle-colour", level_scope));
plot_text_at(OUT,
get_string_mp("subtitle", level_scope),
NULL, 128,
get_string_mp("subtitle-font", level_scope),
border*2, y+vskip,
get_int_mp("subtitle-size", level_scope),
FALSE, FALSE);
} else {
if (get_int_mp("monochrome", level_scope)) EPS_compile_set_greyscale(OUT, 0);
else EPS_compile_set_colour(OUT, get_string_mp("title-colour", level_scope));
plot_text_at(OUT,
get_string_mp("title", NULL),
NULL, 128,
get_string_mp("title-font", level_scope),
border*2, y+2*vskip,
get_int_mp("title-size", level_scope),
FALSE, TRUE);
}
}
#line 906 "inform7/Chapter 19/EPS Map.w"
;
if (eml->contains_rooms) {
instance *R;
LOOP_OVER_ROOMS(R)
if (Room_position(R).z == eml->map_level)
{
#line 993 "inform7/Chapter 19/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 = 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 911 "inform7/Chapter 19/EPS Map.w"
;
LOOP_OVER_ROOMS(R)
if (Room_position(R).z == eml->map_level)
{
#line 1013 "inform7/Chapter 19/EPS Map.w"
map_parameter_scope *room_scope = &(PF_I(map, R)->local_map_parameters);
EPS_compile_line_width_setting(OUT, 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 = get_int_mp("room-size", room_scope)/2;
int R_stiffness = get_int_mp("route-stiffness", room_scope);
int dir;
LOOP_OVER_STORY_DIRECTIONS(dir) {
instance *T = Plugins__Map__room_exit(R, dir, NULL);
int exit = story_dir_to_page_dir[dir];
if (Plugins__Spatial__object_is_a_room(T))
{
#line 1032 "inform7/Chapter 19/EPS Map.w"
int T_stiffness = get_int_mp("route-stiffness", &(PF_I(map, T)->local_map_parameters));
if (get_int_mp("monochrome", level_scope)) EPS_compile_set_greyscale(OUT, 0);
else EPS_compile_set_colour(OUT, get_string_mp("route-colour", level_scope));
if ((Room_position(T).z == Room_position(R).z) &&
(Plugins__Map__room_exit(T, Plugins__Map__opposite(dir), FALSE) == R))
{
#line 1045 "inform7/Chapter 19/EPS Map.w"
if (R->allocation_id <= T->allocation_id)
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, Plugins__Map__opposite(exit));
}
#line 1037 "inform7/Chapter 19/EPS Map.w"
else
{
#line 1055 "inform7/Chapter 19/EPS Map.w"
int scaled = 1;
vector E = Plugins__Map__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;
}
EPS_compile_dashed_arrow(OUT, boxsize/scaled, E, bx, by);
plot_text_at(OUT, NULL, T,
get_int_mp("annotation-length", NULL),
get_string_mp("annotation-font", NULL),
bx+E.x*boxsize*6/scaled/5, by+E.y*boxsize*6/scaled/5,
get_int_mp("annotation-size", NULL),
TRUE, TRUE);
}
#line 1039 "inform7/Chapter 19/EPS Map.w"
;
}
#line 1025 "inform7/Chapter 19/EPS Map.w"
;
}
EPS_compile_line_width_unsetting(OUT);
}
#line 914 "inform7/Chapter 19/EPS Map.w"
;
LOOP_OVER_ROOMS(R)
if (Room_position(R).z == eml->map_level)
{
#line 1074 "inform7/Chapter 19/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 = get_int_mp("room-size", room_scope)/2;
{
#line 1085 "inform7/Chapter 19/EPS Map.w"
WRITE("newpath %% Room interior\n");
if (get_int_mp("monochrome", room_scope)) EPS_compile_set_greyscale(OUT, 75);
else EPS_compile_set_colour(OUT, get_string_mp("room-colour", room_scope));
EPS_compile_room_boundary_path(OUT, bx, by, boxsize, get_string_mp("room-shape", room_scope));
WRITE("fill\n\n");
}
#line 1078 "inform7/Chapter 19/EPS Map.w"
;
{
#line 1094 "inform7/Chapter 19/EPS Map.w"
if (get_int_mp("room-outline", room_scope)) {
EPS_compile_line_width_setting(OUT, get_int_mp("room-outline-thickness", room_scope));
WRITE("newpath %% Room outline\n");
if (get_int_mp("monochrome", level_scope)) EPS_compile_set_greyscale(OUT, 0);
else EPS_compile_set_colour(OUT, get_string_mp("room-outline-colour", room_scope));
EPS_compile_room_boundary_path(OUT, bx, by, boxsize, get_string_mp("room-shape", room_scope));
WRITE("stroke\n");
EPS_compile_line_width_unsetting(OUT);
}
}
#line 1079 "inform7/Chapter 19/EPS Map.w"
;
{
#line 1107 "inform7/Chapter 19/EPS Map.w"
int offs = 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 (get_int_mp("monochrome", level_scope)) EPS_compile_set_greyscale(OUT, 0);
else EPS_compile_set_colour(OUT, get_string_mp("room-name-colour", room_scope));
char *legend = get_string_mp("room-name", room_scope);
instance *room_to_name = NULL;
if (strcmp(legend, "") == 0) { room_to_name = R; legend = NULL; }
plot_text_at(OUT, legend, room_to_name,
get_int_mp("room-name-length", room_scope),
get_string_mp("room-name-font", room_scope),
bx, by, get_int_mp("room-name-size", room_scope),
TRUE, TRUE);
}
#line 1080 "inform7/Chapter 19/EPS Map.w"
;
}
#line 917 "inform7/Chapter 19/EPS Map.w"
;
}
}
{
#line 1128 "inform7/Chapter 19/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 = get_int_mp("grid-size", NULL);
while (xpart > 5000) xpart-=10000;
while (xpart < -5000) xpart+=10000;
if (get_int_mp("monochrome", NULL)) EPS_compile_set_greyscale(OUT, 0);
else 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;
plot_text_at(OUT, rh->annotation, NULL, 128, rh->font, bx, by, rh->point_size,
TRUE, TRUE); /* centred both horizontally and vertically */
}
}
#line 921 "inform7/Chapter 19/EPS Map.w"
;
}
#line 1154 "inform7/Chapter 19/EPS Map.w"
void 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 1171 "inform7/Chapter 19/EPS Map.w"
if (P_printed_name) {
specification *V = World__Inferences__get_prop_state_at(
Data__Instances__as_subject(I), P_printed_name, NULL);
if ((Specifications__Values__is_CONSTANT_of_kind(V, K_text)) &&
(V->word_ref1 >= 0)) {
Extensions__IDs__truncated_strcpy(txt,
Text__word_raw_text(V->word_ref1)+1, MAX_EPS_TEXT_LENGTH);
if ((txt[0]) && (txt[Platform__strlen(txt)-1] == '\"'))
txt[Platform__strlen(txt)-1] = 0;
}
}
}
#line 1161 "inform7/Chapter 19/EPS Map.w"
;
{
#line 1186 "inform7/Chapter 19/EPS Map.w"
if (txt[0] == 0) {
int w1, w2;
Data__Instances__get_name(I, &w1, &w2, FALSE);
if (w1 < 0) return;
Text__print_raw_text_to_string_truncated(w1, w2, txt, MAX_EPS_TEXT_LENGTH);
}
}
#line 1162 "inform7/Chapter 19/EPS Map.w"
;
} else return;
{
#line 1200 "inform7/Chapter 19/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 1164 "inform7/Chapter 19/EPS Map.w"
;
EPS_compile_text(OUT, txt, x, y, font, pointsize, centre_h, centre_v);
}
#line 1222 "inform7/Chapter 19/EPS Map.w"
void 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 1236 "inform7/Chapter 19/EPS Map.w"
void 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 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 1254 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_room_boundary_path(OUTPUT_STREAM, int bx, int by, int boxsize, char *shape) {
if (strcmp(shape, "square") == 0)
EPS_compile_rectangular_path(OUT, bx-boxsize, by-boxsize, bx+boxsize, by+boxsize);
else if (strcmp(shape, "rectangle") == 0)
EPS_compile_rectangular_path(OUT, bx-2*boxsize, by-boxsize, bx+2*boxsize, by+boxsize);
else if (strcmp(shape, "circle") == 0)
EPS_compile_circular_path(OUT, bx, by, boxsize);
else
EPS_compile_rectangular_path(OUT, bx-boxsize, by-boxsize, bx+boxsize, by+boxsize);
}
#line 1268 "inform7/Chapter 19/EPS Map.w"
void 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 1277 "inform7/Chapter 19/EPS Map.w"
void 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 1291 "inform7/Chapter 19/EPS Map.w"
void 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 = Plugins__Map__direction_as_vector(exit0);
cx1 = x0+E.x*stiffness0/100; cy1 = y0+E.y*stiffness0/100;
E = Plugins__Map__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 1309 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_line_width_setting(OUTPUT_STREAM, int new) {
WRITE("currentlinewidth %% Push old line width onto stack\n");
WRITE("%d setlinewidth\n", new);
}
void EPS_compile_line_width_unsetting(OUTPUT_STREAM) {
WRITE("setlinewidth %% Pull old line width from stack\n");
}
#line 1322 "inform7/Chapter 19/EPS Map.w"
void 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 1341 "inform7/Chapter 19/EPS Map.w"
void EPS_compile_set_colour(OUTPUT_STREAM, char *htmlcolour) {
if (Platform__strlen(htmlcolour) != 6) internal_error("Improper HTML colour");
choose_colour_beam(OUT, htmlcolour[0], htmlcolour[1]);
choose_colour_beam(OUT, htmlcolour[2], htmlcolour[3]);
choose_colour_beam(OUT, htmlcolour[4], htmlcolour[5]);
WRITE("setrgbcolor %% From HTML colour %s\n", htmlcolour);
}
void choose_colour_beam(OUTPUT_STREAM, char hex1, char hex2) {
int k = hex_to_int(hex1)*16 + hex_to_int(hex2);
WRITE("%.6g ", (double) (((float) k)/255.0));
}
int 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 1380 "inform7/Chapter 19/EPS Map.w"
void 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 19/Showme Command.w"
void Plugins__Showme__start(void) {
}
#line 31 "inform7/Chapter 19/Showme Command.w"
void Plugins__Showme__compile_SHOWME_details(OUTPUT_STREAM) {
if (Config__Plugins__plugged_in(showme_plugin) == FALSE) return;
compile_SHOWME_type(OUT, FALSE);
compile_SHOWME_type(OUT, TRUE);
}
void compile_SHOWME_type(OUTPUT_STREAM, int val) {
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__le(K, K_object))
compile_SHOWME_type_subj(OUT, val, Kinds__as_subject(K));
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
compile_SHOWME_type_subj(OUT, val, Data__Instances__as_subject(I));
}
void compile_SHOWME_type_subj(OUTPUT_STREAM, int val, inference_subject *subj) {
{
#line 63 "inform7/Chapter 19/Showme Command.w"
int todo = FALSE;
property *prn;
LOOP_OVER(prn, property)
if (Properties__is_value_property(prn) == val)
if (is_property_worth_SHOWME(OUT, subj, prn))
todo = TRUE;
if (todo == FALSE) return;
}
#line 48 "inform7/Chapter 19/Showme Command.w"
;
WRITE("if (");
char cond[1024]; cond[0] = 0;
World__Subjects__write_element_of_condition(subj, cond);
if (cond[0] != 0) WRITE("%s", cond); else WRITE("true");
WRITE(") {");
INDENT;
{
#line 83 "inform7/Chapter 19/Showme Command.w"
char *divider = "; ";
if (val) divider = "^";
WRITE("if (na > 0) { na = 0; print \"%s\"; }\n", divider);
}
#line 55 "inform7/Chapter 19/Showme Command.w"
;
{
#line 90 "inform7/Chapter 19/Showme Command.w"
property *prn;
LOOP_OVER(prn, property)
if (Properties__is_value_property(prn) == val)
compile_property_SHOWME(OUT, subj, prn);
}
#line 56 "inform7/Chapter 19/Showme Command.w"
;
OUTDENT; WRITE("}\n");
}
#line 98 "inform7/Chapter 19/Showme Command.w"
int is_property_worth_SHOWME(OUTPUT_STREAM, inference_subject *subj, property *prn) {
return SHOWME_primitive(OUT, subj, prn, FALSE);
}
void compile_property_SHOWME(OUTPUT_STREAM, inference_subject *subj, property *prn) {
SHOWME_primitive(OUT, subj, prn, TRUE);
}
#line 109 "inform7/Chapter 19/Showme Command.w"
int 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 = World__Subjects__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 19/Showme Command.w"
kind *K = Properties__Valued__kind(prn);
if (K) {
char *P = Properties__get_translation(prn);
char *R = Kinds__get_name_of_printing_rule(K);
int require_nonzero = FALSE;
if ((Properties__Valued__is_used_for_non_typesafe_relation(prn)) ||
(Kinds__le(K, K_object)))
require_nonzero = TRUE;
if (require_nonzero) WRITE("if (GProperty(OBJECT_TY, t_0, %s)) { ", P);
{
#line 164 "inform7/Chapter 19/Showme Command.w"
WRITE("print \"");
Text__print_raw_text_to_stream(prn->word_ref1, prn->word_ref2, OUT);
WRITE(": \"; ");
if (Kinds__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 19/Showme Command.w"
;
if (require_nonzero) WRITE("}\n");
}
}
#line 119 "inform7/Chapter 19/Showme Command.w"
else
{
#line 182 "inform7/Chapter 19/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__Implementation__OfObjects__compile_has_property(OUT, prn);
WRITE(")) { if (na++ > 0) print \", \"; print \"");
Text__print_raw_text_to_stream(prn->word_ref1, prn->word_ref2, OUT);
WRITE("\"; }\n");
}
#line 121 "inform7/Chapter 19/Showme Command.w"
;
}
return TRUE;
}
return FALSE;
}
#line 100 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, scenes_new_property_notify);
PLUGIN_REGISTER(PLUGIN_NEW_INSTANCE_NOTIFY, scenes_new_named_instance_notify);
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, scenes_new_base_kind_notify);
}
#line 109 "inform7/Chapter 19/Scenes.w"
int scenes_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) {
if ((name) && (strcmp(name, "SCENE_TY") == 0)) {
K_scene = new_base; return TRUE;
}
return FALSE;
}
#line 121 "inform7/Chapter 19/Scenes.w"
int notable_scene_properties_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 123 "inform7/Chapter 19/Scenes.w"
#line 127 "inform7/Chapter 19/Scenes.w"
int scenes_new_property_notify(property *prn) {
if (parse_nt_against_word_range(notable_scene_properties_NTM, prn->word_ref1, prn->word_ref2, NULL, NULL)) {
switch (most_recent_result) {
case 0: P_recurring = prn; break;
}
}
return FALSE;
}
#line 140 "inform7/Chapter 19/Scenes.w"
int scenes_new_named_instance_notify(instance *I) {
if ((K_scene) && (Kinds__eq(Data__Instances__kind(I), K_scene))) {
new_scene(I);
return TRUE;
}
return FALSE;
}
#line 153 "inform7/Chapter 19/Scenes.w"
void new_scene(instance *I) {
scene *sc = CREATE(scene);
{
#line 185 "inform7/Chapter 19/Scenes.w"
sc->as_instance = I;
Data__Instances__set_connection(I, STORE_POINTER_scene(sc));
int nw1, nw2;
Data__Instances__get_name(I, &nw1, &nw2, FALSE);
if (parse_nt_against_word_range(notable_scenes_NTM, nw1, nw2, NULL, NULL)) SC_entire_game = sc;
}
#line 155 "inform7/Chapter 19/Scenes.w"
;
{
#line 162 "inform7/Chapter 19/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;
new_scene_rulebook(sc, end);
}
}
#line 156 "inform7/Chapter 19/Scenes.w"
;
}
#line 179 "inform7/Chapter 19/Scenes.w"
int notable_scenes_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 181 "inform7/Chapter 19/Scenes.w"
#line 194 "inform7/Chapter 19/Scenes.w"
scene *Plugins__Scenes__from_named_constant(instance *I) {
if (K_scene == NULL) return NULL;
kind *K = Data__Instances__kind(I);
if (Kinds__eq(K, K_scene))
return RETRIEVE_POINTER_scene(Data__Instances__get_connection(I));
return NULL;
}
void Plugins__Scenes__get_name(scene *sc, int *w1, int *w2) {
Data__Instances__get_name(sc->as_instance, w1, w2, FALSE);
}
#line 209 "inform7/Chapter 19/Scenes.w"
int parse_scene_end_name(scene *sc, int en1, int en2, int create) {
int i;
for (i=2; i<sc->no_ends; i++)
if (Text__compare_word_range(en1, en2, sc->end_names_w1[i], sc->end_names_w2[i]))
return i;
if (create) {
int end = sc->no_ends++;
int max = 31;
if (Code__VirtualMachines__is_16_bit()) max = 15;
if (end >= max)
{
#line 232 "inform7/Chapter 19/Scenes.w"
Problems__sentence_problem(_P_(C19ScenesWithTooManyEnds),
"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 218 "inform7/Chapter 19/Scenes.w"
else {
sc->end_names_w1[end] = en1;
sc->end_names_w2[end] = en2;
new_scene_rulebook(sc, end);
return end;
}
}
return -1;
}
#line 243 "inform7/Chapter 19/Scenes.w"
void new_scene_rulebook(scene *sc, int end) {
int rw1 = -1, rw2 = -1, arw1 = -1, arw2 = -1;
{
#line 260 "inform7/Chapter 19/Scenes.w"
int nw1, nw2;
Data__Instances__get_name(sc->as_instance, &nw1, &nw2, FALSE);
rw1 = lexer_wordcount;
Text__feed_into_lexer("when", TRUE, NULL);
Text__splice_words(nw1, nw2);
Text__feed_into_lexer((end==0)?"begins":"ends", TRUE, NULL);
if (end >= 2) Text__splice_words(sc->end_names_w1[end], sc->end_names_w2[end]);
rw2 = lexer_wordcount - 1;
arw1 = lexer_wordcount;
Text__feed_into_lexer("when the", TRUE, NULL);
Data__Instances__get_name(sc->as_instance, &nw1, &nw2, FALSE);
Text__splice_words(nw1, nw2);
Text__feed_into_lexer((end==0)?"begins":"ends", TRUE, NULL);
if (end >= 2) Text__splice_words(sc->end_names_w1[end], sc->end_names_w2[end]);
arw2 = lexer_wordcount - 1;
}
#line 245 "inform7/Chapter 19/Scenes.w"
;
rulebook *rb = Code__Rulebooks__new_automatic(rw1, rw2, K_action_name,
NO_OUTCOME, FALSE, FALSE, FALSE);
Code__Rulebooks__set_alt_name(rb, arw1, arw2);
sc->end_rulebook[end] = rb;
if (end >= 2)
{
#line 281 "inform7/Chapter 19/Scenes.w"
int nw1, nw2;
Data__Instances__get_name(sc->as_instance, &nw1, &nw2, FALSE);
char i6_code[128];
int wn = lexer_wordcount;
Text__feed_into_lexer("To decide if (S - ", TRUE, NULL);
Text__splice_words(nw1, nw2);
Text__feed_into_lexer(") ended ", TRUE, NULL);
Text__splice_words(sc->end_names_w1[end], sc->end_names_w2[end]);
Parser__Sentences__make_node(wn, lexer_wordcount-1, ':', NULL);
wn = lexer_wordcount;
sprintf(i6_code, " (- (scene_latest_ending-->%d == %d) -) ",
sc->allocation_id, end);
Text__feed_into_lexer(i6_code, TRUE, NULL);
Parser__Sentences__make_node(wn, lexer_wordcount-1, '.', NULL);
wn = lexer_wordcount;
Text__feed_into_lexer("To decide if (S - ", TRUE, NULL);
Text__splice_words(nw1, nw2);
Text__feed_into_lexer(") did not end ", TRUE, NULL);
Text__splice_words(sc->end_names_w1[end], sc->end_names_w2[end]);
Parser__Sentences__make_node(wn, lexer_wordcount-1, ':', NULL);
wn = lexer_wordcount;
sprintf(i6_code, " (- (scene_latest_ending-->%d ~= 0 or %d) -) ",
sc->allocation_id, end);
Text__feed_into_lexer(i6_code, TRUE, NULL);
Parser__Sentences__make_node(wn, lexer_wordcount-1, '.', NULL);
Parser__Sentences__register_recently_lexed_phrases();
}
#line 252 "inform7/Chapter 19/Scenes.w"
;
}
#line 317 "inform7/Chapter 19/Scenes.w"
sentence_handler BEGINS_WHEN_SH_handler =
{ SENTENCE_NT, BEGINS_WHEN_VB, 2, begins_or_ends_when };
sentence_handler ENDS_WHEN_SH_handler =
{ SENTENCE_NT, ENDS_WHEN_VB, 2, begins_or_ends_when };
void begins_or_ends_when(parse_node *p) {
new_scene_anchor(p);
}
scene *scene_end_of_which_parsed = NULL;
#line 342 "inform7/Chapter 19/Scenes.w"
int scene_ends_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 349 "inform7/Chapter 19/Scenes.w"
*X = FALSE;
Problems__sentence_problem(_P_(C19ScenesOnly),
"'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 344 "inform7/Chapter 19/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 345 "inform7/Chapter 19/Scenes.w"
#line 359 "inform7/Chapter 19/Scenes.w"
int scene_ends_sentence_adverb_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 361 "inform7/Chapter 19/Scenes.w"
#line 367 "inform7/Chapter 19/Scenes.w"
int scene_ends_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 380 "inform7/Chapter 19/Scenes.w"
*X = -1;
Problems__sentence_problem(_P_(C19ScenesDisallowCalled),
"'(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 368 "inform7/Chapter 19/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 391 "inform7/Chapter 19/Scenes.w"
*X = -1;
Problems__sentence_problem(_P_(C19ScenesNotPlay),
"'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 370 "inform7/Chapter 19/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 401 "inform7/Chapter 19/Scenes.w"
*X = -1;
Problems__sentence_problem(_P_(C19ScenesUnknownEnd),
"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 374 "inform7/Chapter 19/Scenes.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = -2; specification_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 376 "inform7/Chapter 19/Scenes.w"
#line 411 "inform7/Chapter 19/Scenes.w"
int scene_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 414 "inform7/Chapter 19/Scenes.w"
int scene_name_unarticled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 421 "inform7/Chapter 19/Scenes.w"
instance *I = most_recent_result_p;
if (Data__Instances__of_kind(I, K_scene) == FALSE) return FALSE;
*XP = Plugins__Scenes__from_named_constant(I);
scene_end_of_which_parsed = *XP;
}
#line 416 "inform7/Chapter 19/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 417 "inform7/Chapter 19/Scenes.w"
#line 431 "inform7/Chapter 19/Scenes.w"
int scene_end_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 432 "inform7/Chapter 19/Scenes.w"
int end = parse_scene_end_name(scene_end_of_which_parsed, w1, w2, FALSE);
if (end < 0) return FALSE;
*X = end; return TRUE;
}
int scene_end_name_creating_NTMR(int w1, int w2, int *X, void **XP) {
#line 438 "inform7/Chapter 19/Scenes.w"
*X = parse_scene_end_name(scene_end_of_which_parsed, w1, w2, TRUE);
return TRUE;
}
#line 450 "inform7/Chapter 19/Scenes.w"
void new_scene_anchor(parse_node *p) {
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... */
specification *external_condition = NULL; /* Or: an absolute condition... */
int when_play_begins = FALSE; /* Or: anchor to the start of play */
int sw1 = p->down->next->word_ref1, sw2 = p->down->next->word_ref2; /* scene name */
int en1 = -1, en2 = -1; /* end name, if any */
int cw1 = -1, cw2 = -1; /* condition for end to occur */
if (p->down->next->next->next) {
en1 = p->down->next->next->word_ref1;
en2 = p->down->next->next->word_ref2;
cw1 = p->down->next->next->next->word_ref1;
cw2 = p->down->next->next->next->word_ref2;
} else {
cw1 = p->down->next->next->word_ref1;
cw2 = p->down->next->next->word_ref2;
}
{
#line 522 "inform7/Chapter 19/Scenes.w"
parse_nt_against_word_range(scene_ends_sentence_subject_NTM, sw1, sw2, NULL, NULL);
if (most_recent_result == FALSE) return;
this_scene = most_recent_result_p;
scene_end_of_which_parsed = this_scene;
if (en1 >= 0) {
parse_nt_against_word_range(scene_ends_sentence_adverb_NTM, en1, en2, NULL, NULL);
end = most_recent_result;
} else if (Parser__Nodes__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 472 "inform7/Chapter 19/Scenes.w"
;
if ((this_scene == NULL) || (end < 0)) internal_error("scene misparsed");
{
#line 539 "inform7/Chapter 19/Scenes.w"
if (parse_nt_against_word_range(scene_ends_sentence_object_NTM, cw1, cw2, NULL, NULL)) {
int end = most_recent_result;
switch (end) {
case -2: external_condition = specification_cond_NTMV; break;
case -1: when_play_begins = TRUE; break;
default: other_end = end; other_scene = scene_named_NTMV; break;
}
} else external_condition = Specifications__Unknown__new(cw1, cw2);
}
#line 475 "inform7/Chapter 19/Scenes.w"
;
if ((this_scene == SC_entire_game) && (external_condition == NULL)) {
Problems__sentence_problem(_P_(C19EntireGameHardwired),
"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 493 "inform7/Chapter 19/Scenes.w"
this_scene->start_of_play = TRUE;
}
#line 482 "inform7/Chapter 19/Scenes.w"
else if (other_scene)
{
#line 512 "inform7/Chapter 19/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 484 "inform7/Chapter 19/Scenes.w"
else if (external_condition)
{
#line 498 "inform7/Chapter 19/Scenes.w"
if (this_scene->anchor_condition[end])
Problems__sentence_problem(_P_(C19ScenesOversetEnd),
"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 486 "inform7/Chapter 19/Scenes.w"
else internal_error("failed to obtain an anchor condition");
}
#line 566 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__DetectSceneChange_routine(OUTPUT_STREAM) {
OUT = Code__Routines__begin(OUT, "DetectSceneChange");
Code__LocalVariables__add_internal_local_c("chs", "count of changes made");
Code__LocalVariables__add_internal_local_c("ch", "flag: change made");
scene *sc;
LOOP_OVER(sc, scene)
{
#line 588 "inform7/Chapter 19/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--) test_scene_end(OUT, sc, end);
OUTDENT; WRITE("}\n");
WRITE("if (scene_status-->%d == 0) {\n", ix); INDENT;
test_scene_end(OUT, sc, 0);
OUTDENT; WRITE("}\n");
}
#line 572 "inform7/Chapter 19/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 = Code__Routines__end(OUT);
}
#line 604 "inform7/Chapter 19/Scenes.w"
void 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;
compile_scene_end(OUT, sc, 0);
OUTDENT; WRITE("}\n");
}
specification *S = sc->anchor_condition[end];
if (S) {
{
#line 620 "inform7/Chapter 19/Scenes.w"
current_sentence = sc->anchor_condition_set[end];
if (Specifications__is_UNKNOWN(S)) {
if (parse_nt_against_word_range(spec_condition_NTM, S->word_ref1, S->word_ref2, NULL, NULL)) S = most_recent_result_p;
sc->anchor_condition[end] = S;
}
int m = Specifications__Matching__check(S,
Specifications__Conditions__new_generic_CONDITION());
if (m == NEVER_MATCH) {
LOG("Condition: $S\n", S);
Problems__sentence_problem(_P_(C19ScenesBadCondition),
"'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;
}
}
#line 612 "inform7/Chapter 19/Scenes.w"
;
{
#line 643 "inform7/Chapter 19/Scenes.w"
WRITE("if (");
current_sentence = sc->anchor_condition_set[end];
Specifications__compile(OUT, S);
WRITE(") {\n"); INDENT;
WRITE("ch = true;\n");
compile_scene_end(OUT, sc, end);
WRITE("jump CScene;\n");
OUTDENT; WRITE("}\n");
}
#line 613 "inform7/Chapter 19/Scenes.w"
;
}
}
#line 662 "inform7/Chapter 19/Scenes.w"
void compile_scene_end(OUTPUT_STREAM, scene *sc, int end) {
scene *sc2;
LOOP_OVER(sc2, scene) sc2->marker = 0;
compile_scene_end_dash(OUT, sc, end);
}
#line 677 "inform7/Chapter 19/Scenes.w"
void 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 734 "inform7/Chapter 19/Scenes.w"
WRITE("if (debug_scenes) print \"[Scene '");
if (sc->as_instance) {
int nw1, nw2;
Data__Instances__get_name(sc->as_instance, &nw1, &nw2, FALSE);
Text__print_raw_text_to_stream(nw1, nw2, OUT);
}
WRITE("' ");
if (end == 0) WRITE("begins");
if (end >= 1) WRITE("ends");
if (end >= 2) {
WRITE(" ");
Text__print_raw_text_to_stream(sc->end_names_w1[end], sc->end_names_w2[end], OUT);
}
WRITE("]^\";\n");
}
#line 683 "inform7/Chapter 19/Scenes.w"
;
{
#line 707 "inform7/Chapter 19/Scenes.w"
if (end == 0)
WRITE("scene_status-->%d = 1; ", ix);
else {
WRITE("if (GProperty(%d, %d, %s)) scene_status-->%d = 0; ",
Kinds__RuntimeIDs__weak(K_scene), ix+1,
Properties__get_translation(P_recurring), ix);
WRITE("else scene_status-->%d = 2; ", ix);
}
}
#line 684 "inform7/Chapter 19/Scenes.w"
;
{
#line 726 "inform7/Chapter 19/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 685 "inform7/Chapter 19/Scenes.w"
;
end = e;
}
{
#line 734 "inform7/Chapter 19/Scenes.w"
WRITE("if (debug_scenes) print \"[Scene '");
if (sc->as_instance) {
int nw1, nw2;
Data__Instances__get_name(sc->as_instance, &nw1, &nw2, FALSE);
Text__print_raw_text_to_stream(nw1, nw2, OUT);
}
WRITE("' ");
if (end == 0) WRITE("begins");
if (end >= 1) WRITE("ends");
if (end >= 2) {
WRITE(" ");
Text__print_raw_text_to_stream(sc->end_names_w1[end], sc->end_names_w2[end], OUT);
}
WRITE("]^\";\n");
}
#line 688 "inform7/Chapter 19/Scenes.w"
;
{
#line 707 "inform7/Chapter 19/Scenes.w"
if (end == 0)
WRITE("scene_status-->%d = 1; ", ix);
else {
WRITE("if (GProperty(%d, %d, %s)) scene_status-->%d = 0; ",
Kinds__RuntimeIDs__weak(K_scene), ix+1,
Properties__get_translation(P_recurring), ix);
WRITE("else scene_status-->%d = 2; ", ix);
}
}
#line 689 "inform7/Chapter 19/Scenes.w"
;
{
#line 719 "inform7/Chapter 19/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 690 "inform7/Chapter 19/Scenes.w"
{
#line 726 "inform7/Chapter 19/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 691 "inform7/Chapter 19/Scenes.w"
;
{
#line 761 "inform7/Chapter 19/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;
compile_scene_end_dash(OUT, other_scene, other_end);
OUTDENT; WRITE("}\n");
}
}
}
}
}
#line 692 "inform7/Chapter 19/Scenes.w"
;
if (end >= 2) {
int e = end; end = 1;
{
#line 719 "inform7/Chapter 19/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 696 "inform7/Chapter 19/Scenes.w"
;
{
#line 761 "inform7/Chapter 19/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;
compile_scene_end_dash(OUT, other_scene, other_end);
OUTDENT; WRITE("}\n");
}
}
}
}
}
#line 697 "inform7/Chapter 19/Scenes.w"
;
end = e;
}
}
#line 790 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__ShowSceneStatus_routine(OUTPUT_STREAM) {
OUT = Code__Routines__begin(OUT, "ShowSceneStatus");
Code__LocalVariables__add_internal_local("chs");
Code__LocalVariables__add_internal_local("sc");
Code__LocalVariables__add_internal_local("ch");
scene *sc;
LOOP_OVER(sc, scene) {
int ix = sc->allocation_id;
int nw1, nw2;
Data__Instances__get_name(sc->as_instance, &nw1, &nw2, FALSE);
WRITE("if (scene_status-->%d == 1) {\n", ix); INDENT;
WRITE("print \"Scene '");
Text__print_raw_text_to_stream(nw1, nw2, OUT);
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 '");
Text__print_raw_text_to_stream(nw1, nw2, OUT);
WRITE("' ended\";\n");
if (sc->no_ends > 2) {
WRITE("switch(scene_latest_ending-->%d) {\n", ix); INDENT;
int end;
for (end=2; end<sc->no_ends; end++) {
int w1 = sc->end_names_w1[end], w2 = sc->end_names_w2[end];
WRITE("%d: print \" ", end);
Text__print_raw_text_to_stream(w1, w2, OUT);
WRITE("\";\n");
}
OUTDENT; WRITE("}\n");
}
WRITE("print \"^\";\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
}
OUT = Code__Routines__end(OUT);
}
#line 837 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__PrintSceneName_routine(OUTPUT_STREAM) {
OUT = Code__Routines__begin(OUT, "PrintSceneName");
Code__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);
int nw1, nw2;
Data__Instances__get_name(sc->as_instance, &nw1, &nw2, FALSE);
Text__print_raw_text_to_stream(nw1, nw2, OUT);
WRITE("\";\n");
}
WRITE("default: print \"<no-such-scene>\";\n");
OUTDENT; WRITE("}\n");
OUT = Code__Routines__end(OUT);
}
#line 864 "inform7/Chapter 19/Scenes.w"
int spec_scene_description_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 870 "inform7/Chapter 19/Scenes.w"
if (K_scene == NULL) return FALSE;
specification *spec = RP[1];
instance *I = Specifications__Values__get_named_constant_if_any(spec);
if (((I) && (Data__Instances__of_kind(I, K_scene))) ||
((Specifications__species_is(spec, DESCRIPTION_SPC)) &&
(Kinds__eq(Specifications__Conditions__get_described_kind(spec), K_scene)))) {
*XP = spec;
} else return FALSE;
}
#line 865 "inform7/Chapter 19/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 866 "inform7/Chapter 19/Scenes.w"
#line 883 "inform7/Chapter 19/Scenes.w"
void Plugins__Scenes__test_during_clause(OUTPUT_STREAM, specification *spec) {
if (K_scene == NULL) return;
if (Specifications__family_is(spec, VALUE_FMY)) {
instance *I = Specifications__Values__get_named_constant_if_any(spec);
if (Data__Instances__of_kind(I, K_scene)) {
scene *sc = Plugins__Scenes__from_named_constant(I);
WRITE("if (scene_status-->%d == 1) { ! Runs only during scene\n",
sc->allocation_id);
} else internal_error("non-scene in during");
} else {
WRITE("if (DuringSceneMatching(");
Specifications__Values__coerce_DESCRIPTION_to_VALUE(spec, K_scene);
Specifications__compile(OUT, spec);
WRITE(")) { ! Runs only during scene\n");
}
}
#line 20 "inform7/Chapter 19/Temporal Map.w"
void Plugins__Scenes__index(void) {
int nr = NUMBER_CREATED(scene);
scene **sorted = Memory__I7_calloc(nr, sizeof(scene *), INDEX_SORTING_MREASON);
{
#line 40 "inform7/Chapter 19/Temporal Map.w"
int i = 0;
scene *sc;
LOOP_OVER(sc, scene) sorted[i++] = sc;
qsort(sorted, (size_t) nr, sizeof(scene *), compare_scenes);
}
#line 23 "inform7/Chapter 19/Temporal Map.w"
;
{
#line 54 "inform7/Chapter 19/Temporal Map.w"
int i;
for (i=0; i<nr; i++) {
scene *sc = sorted[i];
if ((sc->start_of_play) || (sc == SC_entire_game))
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))
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)
index_from_scene(sc, 0, NEVER_HAPPENS_END, NULL, sorted, nr);
}
}
#line 25 "inform7/Chapter 19/Temporal Map.w"
;
{
#line 75 "inform7/Chapter 19/Temporal Map.w"
INDEX("<p>Legend: ");
scene_icon_legend("WPB", "Begins when play begins");
INDEX("; ");
scene_icon_legend("WhenC", "can begin whenever some condition holds");
INDEX("; ");
scene_icon_legend("Segue", "follows when a previous scene ends");
INDEX("; ");
scene_icon_legend("Simul", "begins simultaneously");
INDEX("; ");
scene_icon_legend("WNever", "never begins");
INDEX("; ");
scene_icon_legend("ENever", "never ends");
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 19/Temporal Map.w"
;
{
#line 106 "inform7/Chapter 19/Temporal Map.w"
Index__anchor("SDETAILS");
int i;
for (i=0; i<nr; i++) {
INDEX("<hr>");
scene *sc = sorted[i];
{
#line 119 "inform7/Chapter 19/Temporal Map.w"
{
#line 135 "inform7/Chapter 19/Temporal Map.w"
Formats__HTML__open_para(ifl, 1, "hanging");
Index__anchor_numbered(sc->allocation_id);
INDEX("<b>The <i>");
int nw1, nw2;
Plugins__Scenes__get_name(sc, &nw1, &nw2);
Text__print_raw_text_to_stream(nw1, nw2, ifl);
INDEX("</i> scene</b>");
Index__link(sc->scene_declared_at->word_ref1);
if (World__Inferences__get_EO_state(
Data__Instances__as_subject(sc->as_instance), P_recurring) > 0)
INDEX("&nbsp;&nbsp;<i>recurring</i>");
INDEX("</p>");
}
#line 119 "inform7/Chapter 19/Temporal Map.w"
;
if (sc == SC_entire_game)
{
#line 151 "inform7/Chapter 19/Temporal Map.w"
Formats__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 19/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 179 "inform7/Chapter 19/Temporal Map.w"
Formats__HTML__open_para(ifl, 1, "hanging");
INDEX("<i>%s ", (end==0)?"Begins":"Ends");
if (end >= 2) {
Text__print_raw_text_to_stream(sc->end_names_w1[end], sc->end_names_w2[end], ifl);
INDEX(" ");
}
INDEX("when:</i> ");
int count = 0;
{
#line 196 "inform7/Chapter 19/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 187 "inform7/Chapter 19/Temporal Map.w"
;
{
#line 205 "inform7/Chapter 19/Temporal Map.w"
if (sc->anchor_condition[end]) {
if (count > 0) INDEX("<br><i>or when:</i> ");
Text__print_raw_text_to_stream(
sc->anchor_condition[end]->word_ref1,
sc->anchor_condition[end]->word_ref2, ifl);
Index__link(sc->anchor_condition_set[end]->word_ref1);
count++;
}
}
#line 188 "inform7/Chapter 19/Temporal Map.w"
;
{
#line 217 "inform7/Chapter 19/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>");
int nw1, nw2;
Data__Instances__get_name(scon->connect_to->as_instance, &nw1, &nw2, FALSE);
Text__print_raw_text_to_stream(nw1, nw2, ifl);
INDEX("</b> <i>%s</i>", (scon->end==0)?"begins":"ends");
if (scon->end >= 2) {
INDEX(" ");
Text__print_raw_text_to_stream(scon->connect_to->end_names_w1[scon->end],
scon->connect_to->end_names_w2[scon->end], ifl);
}
Index__link(scon->where_said->word_ref1);
count++;
}
}
#line 189 "inform7/Chapter 19/Temporal Map.w"
;
if (count == 0) INDEX("<b>never</b>");
INDEX("</p>");
}
#line 127 "inform7/Chapter 19/Temporal Map.w"
;
{
#line 237 "inform7/Chapter 19/Temporal Map.w"
if (Code__Rulebooks__is_empty(sc->end_rulebook[end], NULL) == FALSE) {
Formats__HTML__open_para(ifl, 1, "hanging");
INDEX("<i>What happens:</i></p>");
int ignore_me = 0;
Code__Rulebooks__index(sc->end_rulebook[end], "", NULL, NULL, &ignore_me);
}
}
#line 128 "inform7/Chapter 19/Temporal Map.w"
;
if (end == 0)
{
#line 159 "inform7/Chapter 19/Temporal Map.w"
int rbc = 0;
rulebook *rb;
LOOP_OVER(rb, rulebook) {
if (Code__Rulebooks__is_empty(rb, sc) == FALSE) {
if (rbc++ == 0) {
Formats__HTML__open_para(ifl, 1, "hanging");
INDEX("<i>During this scene:</i></p>");
}
Formats__HTML__open_para(ifl, 2, "hanging");
INDEX("<i>");
Text__print_raw_text_to_stream(rb->word_ref1, rb->word_ref2, ifl);
INDEX("</i></p>");
int ignore_me = 0;
Code__Rulebooks__index(rb, "", sc, NULL, &ignore_me);
}
}
}
#line 129 "inform7/Chapter 19/Temporal Map.w"
;
}
}
#line 111 "inform7/Chapter 19/Temporal Map.w"
;
}
}
#line 27 "inform7/Chapter 19/Temporal Map.w"
;
Memory__I7_free(sorted, INDEX_SORTING_MREASON);
}
void Plugins__Scenes__index_rules(void) {
Code__Rulebooks__index_scene(); /* rules in generic scene-ending rulebooks */
{
#line 95 "inform7/Chapter 19/Temporal Map.w"
INDEX("<p>");
Index__anchor("SRULES");
INDEX("<b>General rules applying to scene changes</b><p>");
Code__Rulebooks__index_rules_box("When a scene begins", -1, -1, NULL,
built_in_rulebooks[WHEN_SCENE_BEGINS_RB], NULL, NULL, 1, FALSE);
Code__Rulebooks__index_rules_box("When a scene ends", -1, -1, NULL,
built_in_rulebooks[WHEN_SCENE_ENDS_RB], NULL, NULL, 1, FALSE);
}
#line 34 "inform7/Chapter 19/Temporal Map.w"
;
}
#line 260 "inform7/Chapter 19/Temporal Map.w"
void index_from_scene(scene *sc, int depth, int end, scene *sc_from, scene **sorted, int nr) {
Formats__HTML__open_para(ifl, depth+1, "tight");
{
#line 277 "inform7/Chapter 19/Temporal Map.w"
switch(end) {
case 0: scene_icon("Simul"); break;
case 1: scene_icon("Segue"); break;
case START_OF_PLAY_END: break;
case NEVER_HAPPENS_END: scene_icon("WNever"); break;
default:
scene_icon("Segue");
INDEX("[ends ");
int w1 = sc_from->end_names_w1[end], w2 = sc_from->end_names_w2[end];
Text__print_raw_text_to_stream(w1, w2, ifl);
INDEX("]&nbsp;"); break;
}
if ((sc->indexed == FALSE) || (depth == 0)) {
if (sc == SC_entire_game) scene_icon("WPB");
else if (sc->anchor_condition[0]) scene_icon("WhenC");
if (sc->start_of_play) scene_icon("WPB");
}
}
#line 262 "inform7/Chapter 19/Temporal Map.w"
;
{
#line 298 "inform7/Chapter 19/Temporal Map.w"
if (sc->indexed) INDEX("<i>");
int nw1, nw2;
Data__Instances__get_name(sc->as_instance, &nw1, &nw2, FALSE);
Text__print_raw_text_to_stream(nw1, nw2, ifl);
if (sc->indexed) INDEX("</i>");
else Index__below_link_numbered(sc->allocation_id);
}
#line 263 "inform7/Chapter 19/Temporal Map.w"
;
if (sc->indexed == FALSE) {
{
#line 308 "inform7/Chapter 19/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) scene_icon_append("ENever");
}
#line 265 "inform7/Chapter 19/Temporal Map.w"
;
{
#line 318 "inform7/Chapter 19/Temporal Map.w"
inference_subject *subj = Data__Instances__as_subject(sc->as_instance);
if (World__Inferences__get_EO_state(subj, P_recurring) > UNKNOWN_CE)
scene_icon_append("Recurring");
}
#line 266 "inform7/Chapter 19/Temporal Map.w"
;
}
INDEX("</p>");
if (sc->indexed) return;
sc->indexed = TRUE;
{
#line 328 "inform7/Chapter 19/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))
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))
index_from_scene(sc2, depth, scon->end, sc, sorted, nr);
}
}
#line 271 "inform7/Chapter 19/Temporal Map.w"
;
}
#line 347 "inform7/Chapter 19/Temporal Map.w"
void scene_icon(char *si) {
scene_icon_unspaced(si); INDEX("&nbsp;&nbsp;");
}
void scene_icon_append(char *si) {
INDEX("&nbsp;&nbsp;"); scene_icon_unspaced(si);
}
void scene_icon_legend(char *si, char *gloss) {
scene_icon_unspaced(si); INDEX("&nbsp;<i>%s</i>", gloss);
}
void scene_icon_unspaced(char *si) {
INDEX("<img border=0 src=inform:/scene_icons/%s.png>", si);
}
#line 368 "inform7/Chapter 19/Temporal Map.w"
int 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;
int sc11, sc12, sc21, sc22;
Data__Instances__get_name(sc1->as_instance, &sc11, &sc12, FALSE);
Data__Instances__get_name(sc2->as_instance, &sc21, &sc22, FALSE);
return Text__rangecmp(sc11, sc12, sc21, sc22);
}
#line 93 "inform7/Chapter 20/Text Literals.w"
int wn_quote_suppressed = -1;
void Data__Strings__suppress_quote_expansion(int w1) {
wn_quote_suppressed = w1;
}
#line 102 "inform7/Chapter 20/Text Literals.w"
literal_text *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->word_ref1 = 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 20/Text Literals.w"
int lt_cmp(int w1, literal_text *lt) {
if (lt == NULL) return 1;
if (lt->word_ref1 < 0) return 1;
return strcmp(Text__word_text(w1), Text__word_text(lt->word_ref1));
}
#line 130 "inform7/Chapter 20/Text Literals.w"
void Data__Strings__mark_as_unescaped(literal_text *lt) {
if (lt) lt->unescaped = TRUE;
}
#line 137 "inform7/Chapter 20/Text Literals.w"
literal_text *Data__Strings__compile_literal(OUTPUT_STREAM, int w1) {
if (divert_constant_text_bibliographically) {
Formats__HTML__compile_bibliographic_text(OUT, Text__word_text(w1));
return NULL;
}
if (strcmp(Text__word_text(w1), "\"\"") == 0) {
WRITE("EMPTY_TEXT_VALUE");
return NULL;
}
if (z_node == NULL)
{
#line 158 "inform7/Chapter 20/Text Literals.w"
z_node = lt_new(-1, BLACK_NODE); z_node->left_node = z_node; z_node->right_node = z_node;
root_of_literal_text = lt_new(-1, BLACK_NODE);
root_of_literal_text->left_node = z_node;
root_of_literal_text->right_node = z_node;
}
#line 146 "inform7/Chapter 20/Text Literals.w"
;
{
#line 166 "inform7/Chapter 20/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 = lt_cmp(w1, x);
if (sgn == 0)
{
#line 190 "inform7/Chapter 20/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 171 "inform7/Chapter 20/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 200 "inform7/Chapter 20/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 209 "inform7/Chapter 20/Text Literals.w"
g->node_colour = RED_NODE;
int left_of_g = FALSE, left_of_p = FALSE;
if (lt_cmp(w1, g) < 0) left_of_g = TRUE;
if (lt_cmp(w1, p) < 0) left_of_p = TRUE;
if (left_of_g != left_of_p) p = rotate(w1, g);
x = rotate(w1, gg);
x->node_colour = BLACK_NODE;
}
#line 203 "inform7/Chapter 20/Text Literals.w"
;
root_of_literal_text->right_node->node_colour = BLACK_NODE;
}
#line 176 "inform7/Chapter 20/Text Literals.w"
;
} while (x != z_node);
x = 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 200 "inform7/Chapter 20/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 209 "inform7/Chapter 20/Text Literals.w"
g->node_colour = RED_NODE;
int left_of_g = FALSE, left_of_p = FALSE;
if (lt_cmp(w1, g) < 0) left_of_g = TRUE;
if (lt_cmp(w1, p) < 0) left_of_p = TRUE;
if (left_of_g != left_of_p) p = rotate(w1, g);
x = rotate(w1, gg);
x->node_colour = BLACK_NODE;
}
#line 203 "inform7/Chapter 20/Text Literals.w"
;
root_of_literal_text->right_node->node_colour = BLACK_NODE;
}
#line 183 "inform7/Chapter 20/Text Literals.w"
;
x = new_x;
{
#line 190 "inform7/Chapter 20/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 185 "inform7/Chapter 20/Text Literals.w"
;
}
#line 147 "inform7/Chapter 20/Text Literals.w"
;
}
#line 222 "inform7/Chapter 20/Text Literals.w"
literal_text *rotate(int w1, literal_text *y) {
literal_text *c, *gc;
if (lt_cmp(w1, y) < 0) c = y->left_node; else c = y->right_node;
if (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 (lt_cmp(w1, y) < 0) y->left_node = gc; else y->right_node = gc;
return gc;
}
#line 244 "inform7/Chapter 20/Text Literals.w"
int extent_of_runtime_quotations_array = 1; /* start at 1 to avoid 0 length */
void Data__Strings__compile_quotation(OUTPUT_STREAM, int w1) {
literal_text *lt = Data__Strings__compile_literal(OUT, w1);
lt->as_boxed_quotation = TRUE;
extent_of_runtime_quotations_array++;
}
#line 255 "inform7/Chapter 20/Text Literals.w"
literal_text *Data__Strings__compile_literal_from_text(OUTPUT_STREAM, char *p) {
Text__feed_into_lexer(p, FALSE, NULL);
return Data__Strings__compile_literal(OUT, lexer_feed_w1);
}
#line 268 "inform7/Chapter 20/Text Literals.w"
void Data__Strings__compile(OUTPUT_STREAM) {
traverse_lts(OUT, root_of_literal_text);
}
void traverse_lts(OUTPUT_STREAM, literal_text *lt) {
if (lt->left_node != z_node) traverse_lts(OUT, lt->left_node);
if (lt->word_ref1 >= 0) {
if (lt->as_boxed_quotation == FALSE)
{
#line 286 "inform7/Chapter 20/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 = ISN_DEQUOTE + ISN_EXPAND_APOSTROPHES;
if (lt->unescaped) options = ISN_DEQUOTE;
if (lt->bibliographic_conventions)
options += ISN_RECOGNISE_APOSTROPHE_SUBSTITUTION + ISN_RECOGNISE_UNICODE_SUBSTITUTION;
if (lt->unexpanded) options = ISN_DEQUOTE;
Formats__Inform6__compile_string(OUT, Text__word_text(lt->word_ref1), 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 276 "inform7/Chapter 20/Text Literals.w"
else
{
#line 307 "inform7/Chapter 20/Text Literals.w"
OUT = Code__Routines__begin_numbered(OUT, "TX_L_%d", lt->allocation_id);
WRITE("box\n\""); INDENT;
Formats__Inform6__compile_string(OUT, Text__word_text(lt->word_ref1),
ISN_DEQUOTE + ISN_BOX_QUOTATION);
WRITE("\";\n");
OUTDENT;
OUT = Code__Routines__end(OUT);
}
#line 278 "inform7/Chapter 20/Text Literals.w"
;
}
if (lt->right_node != z_node) traverse_lts(OUT, lt->right_node);
}
#line 318 "inform7/Chapter 20/Text Literals.w"
void Data__Strings__compile_small_block(OUTPUT_STREAM, literal_text *lt) {
}
#line 324 "inform7/Chapter 20/Text Literals.w"
literal_text *Data__Strings__compile_literal_sb(OUTPUT_STREAM, int w1) {
literal_text *lt = NULL;
if (TEST_COMPILATION_MODE(CONSTANT_CMODE)) {
STREAM *BC = Kinds__RunTime__begin_block_constant(OUT, K_text);
lt = Data__Strings__compile_literal(NULL, w1);
STREAM_WRITE(BC, "PACKED_TEXT_STORAGE ");
if (lt == NULL) STREAM_WRITE(BC, "EMPTY_TEXT_PACKED");
else STREAM_WRITE(BC, "TX_PS_%d", lt->allocation_id);
Kinds__RunTime__end_block_constant(K_text);
} else {
lt = Data__Strings__compile_literal(OUT, w1);
}
return lt;
}
#line 67 "inform7/Chapter 20/Text Substitutions.w"
text_substitution *Data__Strings__new_text_substitution(int wn,
ph_stack_frame *phsf, rule *R, int marker) {
text_substitution *ts = CREATE(text_substitution);
if (no_further_text_subs)
{
#line 102 "inform7/Chapter 20/Text Substitutions.w"
if (divert_constant_text_bibliographically)
Problems__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 70 "inform7/Chapter 20/Text Substitutions.w"
;
ts->word_ref1 = -1; ts->word_ref2 = -1;
ts->wn = wn;
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 = Code__Frames__new();
ts->parked_stack_frame = Code__Frames__boxed_frame(&new_frame);
if (phsf) Code__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) &&
(Code__LocalVariables__count(Code__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 %d $W %08x\n",
ts->allocation_id, (int) phsf, wn, wn, wn, R);
return ts;
}
#line 112 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__allow_no_further_text_subs(void) {
no_further_text_subs = TRUE;
}
#line 120 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__text_substitution_name(OUTPUT_STREAM, text_substitution *ts) {
WRITE("%s", ts->ts_identifier);
ts->ts_sb_needed = TRUE;
}
#line 134 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__text_substitution_cue(OUTPUT_STREAM, int wn) {
if (adopted_rule_for_compilation) {
Code__Rules__log(adopted_rule_for_compilation);
LOG(" Hello! %d\n", adopted_marker_for_compilation);
}
ph_stack_frame *phsf = NULL;
if (adopted_rule_for_compilation) {
{
#line 161 "inform7/Chapter 20/Text Substitutions.w"
text_substitution *ts = Data__Strings__new_text_substitution(wn, phsf,
adopted_rule_for_compilation, adopted_marker_for_compilation);
if (TEST_COMPILATION_MODE(CONSTANT_CMODE)) {
STREAM *BC = Kinds__RunTime__begin_block_constant(OUT, K_text);
STREAM_WRITE(BC, "CONSTANT_PACKED_TEXT_STORAGE R_%s", ts->ts_identifier);
Kinds__RunTime__end_block_constant(K_text);
} else {
Data__Strings__text_substitution_name(OUT, ts);
}
}
#line 141 "inform7/Chapter 20/Text Substitutions.w"
;
} else {
if (TEST_COMPILATION_MODE(PERMIT_LOCALS_IN_TEXT_CMODE)) {
if (phsf == NULL) phsf = Code__Frames__current_stack_frame();
WRITE("(");
Code__LocalVariables__compile_storage(OUT, phsf);
phsf = Code__Frames__boxed_frame(phsf);
WRITE("TEXT_TY_ExpandIfPerishable(");
Code__Frames__compile_allocation(OUT, K_text);
WRITE(",");
}
{
#line 161 "inform7/Chapter 20/Text Substitutions.w"
text_substitution *ts = Data__Strings__new_text_substitution(wn, phsf,
adopted_rule_for_compilation, adopted_marker_for_compilation);
if (TEST_COMPILATION_MODE(CONSTANT_CMODE)) {
STREAM *BC = Kinds__RunTime__begin_block_constant(OUT, K_text);
STREAM_WRITE(BC, "CONSTANT_PACKED_TEXT_STORAGE R_%s", ts->ts_identifier);
Kinds__RunTime__end_block_constant(K_text);
} else {
Data__Strings__text_substitution_name(OUT, ts);
}
}
#line 152 "inform7/Chapter 20/Text Substitutions.w"
;
if (TEST_COMPILATION_MODE(PERMIT_LOCALS_IN_TEXT_CMODE))
WRITE("))");
}
}
#line 175 "inform7/Chapter 20/Text Substitutions.w"
text_substitution *current_ts_being_compiled = NULL;
void Data__Strings__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)) {
Code__Frames__log(Code__Frames__current_stack_frame());
Problems__quote_words(9,
current_ts_being_compiled->word_ref1, current_ts_being_compiled->word_ref2);
Problems__issue_problem_segment( /* test with |XLocalInSubstitution| */
" %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 210 "inform7/Chapter 20/Text Substitutions.w"
text_substitution *latest_ts_compiled = NULL;
int Data__Strings__compilation_coroutine(OUTPUT_STREAM, int in_response_mode) {
Data__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)) {
Data__Strings__compile_single_substitution(OUT, ts);
}
N++;
}
compiling_text_routines_mode = FALSE;
return N;
}
#line 240 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__compile_single_substitution(OUTPUT_STREAM, text_substitution *ts) {
current_ts_being_compiled = ts;
ts->tr_done_already = TRUE;
char ts_name[32];
sprintf(ts_name, "R_%s", ts->ts_identifier);
OUT = Code__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 = Code__Rules__rule_defines_response(
ts->responding_to_rule, ts->responding_to_marker);
if (resp) phsf = Data__Strings__frame_for_response(resp);
}
if (phsf) Code__LocalVariables__copy(Code__Frames__current_stack_frame(), phsf);
Code__LocalVariables__monitor_local_parsing(Code__Frames__current_stack_frame());
int lw1 = -1, lw2 = -1;
{
#line 284 "inform7/Chapter 20/Text Substitutions.w"
lw1 = lexer_wordcount;
Text__feed_into_lexer(" say ", FALSE, NULL);
Text__splice_words(ts->wn, ts->wn);
lw2 = lexer_wordcount - 1;
Text__feed_into_lexer(" . ", FALSE, NULL);
current_sentence = ts->sentence_using_this;
ts->word_ref1 = lw1;
ts->word_ref2 = lw2;
LOGIF(TEXT_SUBSTITUTIONS,
"Compiling text routine %d\n$W (=%d, %d)\n"
"With current sentence:\n$P",
ts->allocation_id, lw1, lw2, lw1, lw2, current_sentence);
}
#line 256 "inform7/Chapter 20/Text Substitutions.w"
;
{
#line 303 "inform7/Chapter 20/Text Substitutions.w"
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEFINING_TEXT_SUB_CMODE);
COMPILATION_MODE_EXIT(IMPLY_NEWLINES_IN_SAY_CMODE);
WRITE("#ifdef DEBUG; if (suppress_text_substitution) { print \"");
Text__print_raw_text_within_i6_literal(OUT, lw2, lw2);
WRITE("\"; rtrue; }\n");
WRITE("#endif; ! DEBUG\n");
Code__Routines__ToPhrases__compile_line(OUT, lw1, lw2);
END_COMPILATION_MODE;
WRITE("\n");
}
#line 257 "inform7/Chapter 20/Text Substitutions.w"
;
WRITE("rtrue;\n");
int makes_local_references =
Code__LocalVariables__local_parsed_recently(Code__Frames__current_stack_frame());
OUT = Code__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);
}
Parser__SP__MeaningLists__finish_this_session();
current_ts_being_compiled = NULL;
}
#line 320 "inform7/Chapter 20/Text Substitutions.w"
void Data__Strings__compile_text_routines_in_response_mode(OUTPUT_STREAM) {
latest_ts_compiled = NULL;
Data__Strings__compilation_coroutine(OUT, TRUE);
latest_ts_compiled = NULL;
}
#line 34 "inform7/Chapter 20/Responses.w"
void response_launcher_name(OUTPUT_STREAM, response_message *resp) {
WRITE("TX_R_%d", resp->allocation_id);
}
#line 42 "inform7/Chapter 20/Responses.w"
void Data__Strings__compile_response_constant(OUTPUT_STREAM, rule *R, int marker) {
WRITE("R_%d_RESP_%c", R->allocation_id, 'A'+marker);
}
#line 65 "inform7/Chapter 20/Responses.w"
response_message *Data__Strings__response_cue(OUTPUT_STREAM, rule *owner, int marker,
int wn, ph_stack_frame *phsf, int via_I6) {
response_message *resp = CREATE(response_message);
resp->original_stack_frame = Code__Frames__boxed_frame(phsf);
resp->responding_rule = owner;
resp->response_marker = marker;
resp->original_text = Data__Strings__new_text_substitution(wn, phsf, owner, marker);
resp->launcher_compiled = FALSE;
resp->via_I6 = via_I6;
resp->via_I6_routine_compiled = FALSE;
if (OUT) response_launcher_name(OUT, resp);
return resp;
}
#line 85 "inform7/Chapter 20/Responses.w"
void Data__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 20/Responses.w"
WRITE("Array TX_R_%d --> CONSTANT_PACKED_TEXT_STORAGE TX_R_%d_R;\n",
resp->allocation_id, resp->allocation_id);
OUT = Code__Routines__begin_numbered(OUT, "TX_R_%d_R", resp->allocation_id);
WRITE("ResponseViaActivity(");
Data__Strings__compile_response_constant(OUT,
resp->responding_rule, resp->response_marker);
WRITE(");\n");
OUT = Code__Routines__end(OUT);
}
#line 90 "inform7/Chapter 20/Responses.w"
;
if ((resp->via_I6) && (resp->via_I6_routine_compiled == FALSE))
{
#line 129 "inform7/Chapter 20/Responses.w"
char rname[33];
sprintf(rname, "%sM", Code__Rules__get_I6_definition(resp->responding_rule));
OUT = Code__Routines__begin(OUT, rname);
Code__LocalVariables__add_named_call("code");
Code__LocalVariables__add_named_call("val");
Code__LocalVariables__add_named_call("val2");
Code__LocalVariables__add_internal_local("s");
Code__LocalVariables__add_internal_local("s2");
Code__LocalVariables__add_internal_local("s3");
Code__LocalVariables__add_internal_local("str");
Code__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);
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 = Code__Routines__end(OUT);
}
#line 92 "inform7/Chapter 20/Responses.w"
;
}
}
}
#line 165 "inform7/Chapter 20/Responses.w"
void Data__Strings__compile_responses(OUTPUT_STREAM) {
{
#line 179 "inform7/Chapter 20/Responses.w"
rule *R;
int tally = 0;
LOOP_OVER(R, rule) {
int marker;
for (marker = 0; marker < 26; marker++) {
response_message *resp = Code__Rules__rule_defines_response(R, marker);
if (resp)
WRITE("Constant R_%d_RESP_%c = %d;\n",
resp->responding_rule->allocation_id, 'A' + marker,
++tally);
}
}
WRITE("Constant NO_RESPONSES = %d;\n", tally);
}
#line 166 "inform7/Chapter 20/Responses.w"
;
{
#line 197 "inform7/Chapter 20/Responses.w"
WRITE("Array ResponseTexts -->\n"); INDENT;
rule *R;
LOOP_OVER(R, rule) {
int marker;
for (marker = 0; marker < 26; marker++) {
response_message *resp = Code__Rules__rule_defines_response(R, marker);
if (resp) {
text_substitution *ts = resp->original_text;
int wn = Code__Rules__get_response_wn(R, marker);
if (wn >= 0) { /* i.e., if the rule gives us a better text */
current_sentence = Code__Rules__get_response_sentence(R, marker);
ts = Data__Strings__new_text_substitution(wn,
NULL, R, marker);
resp->original_text->dont_need_after_all = TRUE;
}
Data__Strings__text_substitution_name(OUT, ts);
WRITE(" ");
}
}
}
OUTDENT; WRITE("0 0;\n");
}
#line 167 "inform7/Chapter 20/Responses.w"
;
{
#line 224 "inform7/Chapter 20/Responses.w"
OUT = Code__Routines__begin(OUT, "PrintResponse");
Code__LocalVariables__add_named_call("R");
response_message *resp;
LOOP_OVER(resp, response_message) {
WRITE("if (R == ");
Data__Strings__compile_response_constant(OUT,
resp->responding_rule,
resp->response_marker);
WRITE(") print (RulePrintingRule) ");
Code__Rules__compile(OUT, resp->responding_rule);
WRITE(", \" response (%c)\";\n", 'A' + resp->response_marker);
}
OUT = Code__Routines__end(OUT);
}
#line 168 "inform7/Chapter 20/Responses.w"
;
{
#line 242 "inform7/Chapter 20/Responses.w"
OUT = Code__Routines__begin(OUT, "STANDARD_RESPONSE_ISSUING_R");
WRITE("RegardingSingleObject(); TEXT_TY_Say(ResponseTexts-->(parameter_value-1));\n");
OUT = Code__Routines__end(OUT);
}
#line 169 "inform7/Chapter 20/Responses.w"
;
{
#line 251 "inform7/Chapter 20/Responses.w"
WRITE("Array ResponseDivisions -->\n"); INDENT;
extension_file *group_ef = NULL;
int ef_active = FALSE;
rule *R;
int tally = 0;
LOOP_OVER(R, rule) {
int marker;
for (marker = 0; marker < 26; marker++) {
response_message *resp = Code__Rules__rule_defines_response(R, marker);
if (resp) {
extension_file *ef = Text__Reader__sf_get_extension_corresponding(
Text__file_of_origin(R->word_ref1));
tally++;
if ((ef_active == FALSE) || (ef != group_ef)) {
if (ef_active) { WRITE("%d\n", tally - 1); }
group_ef = ef;
ef_active = TRUE;
extension_identifier *eid = Extensions__Files__get_eid(ef);
WRITE("\"");
if (eid == NULL) WRITE("source text");
else Extensions__IDs__write_to_I6_file(OUT, eid);
WRITE("\" %d ", tally);
}
}
}
}
if (ef_active) { WRITE("%d\n", tally); }
WRITE("0 0 0;\n");
OUTDENT;
}
#line 170 "inform7/Chapter 20/Responses.w"
;
Data__Strings__compile_text_routines_in_response_mode(OUT);
}
#line 284 "inform7/Chapter 20/Responses.w"
ph_stack_frame *Data__Strings__frame_for_response(response_message *resp) {
if (resp == NULL) return NULL;
return resp->original_stack_frame;
}
#line 293 "inform7/Chapter 20/Responses.w"
void Data__Strings__assert_response_value(rule *R, int marker, int wn) {
Code__Rules__now_rule_needs_response(R, marker, wn);
}
#line 301 "inform7/Chapter 20/Responses.w"
void Data__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);
int wn = resp->original_text->wn;
INDEX("<span style=\"color: #000066;\">");
Text__print_raw_text_to_stream(wn, wn, ifl);
INDEX("</span>");
INDEX("&nbsp;&nbsp;");
char S[2*MAX_PASTEABLE_RULE_NAME_LENGTH + 50];
Text__print_raw_text_to_string_truncated(R->word_ref1, R->word_ref2,
S, MAX_PASTEABLE_RULE_NAME_LENGTH);
sprintf(S+Platform__strlen(S), " response (%c)", 'A' + marker);
Formats__HTML__Javascript__paste(ifl, -1, -1, S);
INDEX("&nbsp;<i>name</i>");
INDEX("&nbsp;");
Text__print_raw_text_to_string_truncated(R->word_ref1, R->word_ref2,
S, MAX_PASTEABLE_RULE_NAME_LENGTH);
sprintf(S+Platform__strlen(S), " response (%c) is \"New text.\".", 'A' + marker);
Formats__HTML__Javascript__paste(ifl, -1, -1, S);
INDEX("&nbsp;<i>set</i>");
}
#line 328 "inform7/Chapter 20/Responses.w"
int Data__Strings__get_marker_from_response_spec(specification *rs) {
if (Specifications__Values__is_actual_CONSTANT_of_kind(rs, K_response)) {
int s1 = rs->word_ref1, s2 = rs->word_ref2;
if (s1 < 0) internal_error("bad response spec");
if ((s2 > s1) && (parse_nt_against_word_range(response_letter_NTM, s2-1, s2-1, NULL, NULL)))
return most_recent_result;
}
return -1;
}
#line 352 "inform7/Chapter 20/Responses.w"
void Data__Strings__compile_general(OUTPUT_STREAM, specification *str) {
int s1 = str->word_ref1, s2 = str->word_ref2;
if (Specifications__test_flag(str, EXPLICIT_LITERAL_SPFLAG)) {
STREAM *S = RETRIEVE_POINTER_STREAM(Specifications__get_structure_field(str));
STREAM_COPY(OUT, S);
STREAM_CLOSE(S);
return;
}
if (s1 < 0) internal_error("Text no longer available for CONSTANT/TEXT");
if (TEST_COMPILATION_MODE(COMPILE_TEXT_TO_QUOT_CMODE)) {
Data__Strings__compile_quotation(OUT, s1);
} else if (divert_constant_text_bibliographically) {
Formats__HTML__compile_bibliographic_text(OUT, Text__word_text(s1));
} else
{
#line 375 "inform7/Chapter 20/Responses.w"
if ((s2 > s1) && (parse_nt_against_word_range(response_letter_NTM, s2-1, s2-1, NULL, NULL)))
{
#line 381 "inform7/Chapter 20/Responses.w"
int code = most_recent_result;
if ((rule_being_compiled == NULL) ||
(Code__Rules__rule_is_named(rule_being_compiled) == FALSE)) {
Problems__sentence_problem(_P_(C20ResponseContextWrong),
"lettered responses can only be used in named rules",
"not in any of the other contexts in which quoted text can appear.");
return;
}
if (Code__Rules__rule_defines_response(rule_being_compiled, code)) {
Problems__sentence_problem(_P_(C20ResponseDuplicated),
"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 = Code__Frames__current_stack_frame();
WRITE("(");
Code__LocalVariables__compile_storage(OUT, phsf);
response_message *resp =
Data__Strings__response_cue(OUT, rule_being_compiled, code, s1,
Code__Frames__boxed_frame(phsf), FALSE);
Code__Rules__now_rule_defines_response(rule_being_compiled, code, resp);
WRITE(")");
}
#line 375 "inform7/Chapter 20/Responses.w"
else
{
#line 408 "inform7/Chapter 20/Responses.w"
if (Specifications__get_data(str, TEXT_UNESCAPED_SPDATA) == 1) {
literal_text *lt = Data__Strings__compile_literal_sb(OUT, s1);
Data__Strings__mark_as_unescaped(lt);
} else if (Text__Vocabulary__test_flags(s1, TEXTWITHSUBS_MC)) {
Data__Strings__text_substitution_cue(OUT, s1);
} else {
Data__Strings__compile_literal_sb(OUT, s1);
}
}
#line 376 "inform7/Chapter 20/Responses.w"
;
}
#line 365 "inform7/Chapter 20/Responses.w"
;
}
#line 62 "inform7/Chapter 20/Nonlocal Variables.w"
int notable_variables_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 65 "inform7/Chapter 20/Nonlocal Variables.w"
#line 71 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable *Data__NonlocalVariables__new_global(int w1, int w2, kind *K) {
PROTECTED_MODEL_PROCEDURE;
return new_nonlocal_variable(w1, w2, K, NULL);
}
nonlocal_variable *Data__NonlocalVariables__new_stacked(int w1, int w2, kind *K,
stacked_variable *scope) {
if (scope == NULL) internal_error("not a stacked nonlocal_variable at all");
return new_nonlocal_variable(w1, w2, K, scope);
}
#line 85 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable *new_nonlocal_variable(int w1, int w2, kind *K, stacked_variable *scope) {
if (K == NULL) internal_error("created variable without kind");
if (Kinds__definite(K) == FALSE)
{
#line 103 "inform7/Chapter 20/Nonlocal Variables.w"
Problems__quote_words(1, w1, w2);
Problems__quote_kind(2, K);
Problems__handmade_problem(_P_(C20IndefiniteVariable));
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 87 "inform7/Chapter 20/Nonlocal Variables.w"
;
nonlocal_variable *nlv = CREATE(nonlocal_variable);
{
#line 132 "inform7/Chapter 20/Nonlocal Variables.w"
nlv->var_documentation_symbol_wn = Index__DocReferences__position_of_symbol(&w1, &w2);
nlv->word_ref1 = w1; nlv->word_ref2 = w2;
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;
if ((w1 >= 0) && (scope == NULL)) /* that is, if it's a global */
Semantics__Nouns__ExcerptMeanings__register(VARIABLE_MC, 0, w1, w2,
STORE_POINTER_nonlocal_variable(nlv));
nlv->nlv_knowledge =
World__Subjects__new(nonlocal_variables,
VARI_SUB, STORE_POINTER_nonlocal_variable(nlv), CERTAIN_CE);
}
#line 90 "inform7/Chapter 20/Nonlocal Variables.w"
;
latest_nonlocal_variable = nlv;
{
#line 117 "inform7/Chapter 20/Nonlocal Variables.w"
if (parse_nt_against_word_range(notable_variables_NTM, w1, w2, NULL, NULL)) {
switch (most_recent_result) {
case 0: i6_glob_VAR = nlv; break;
case 1: i6_nothing_VAR = nlv; break;
}
}
}
#line 93 "inform7/Chapter 20/Nonlocal Variables.w"
;
Config__Plugins__Call__new_variable_notify(nlv);
LOGIF(VARIABLE_CREATIONS, "Created non-library variable: $Z\n", nlv);
return nlv;
}
#line 155 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__log(nonlocal_variable *nlv) {
if (nlv== NULL) { LOG("<null variable>"); return; }
LOG("'$W'(%s)[$u]", nlv->word_ref1, nlv->word_ref2,
(nlv->constant_at_run_time)?"const":"var",
nlv->nlv_kind);
}
#line 166 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable *Data__NonlocalVariables__parse(int w1, int w2) {
Text__Languages__remove_the(&w1, &w2);
if (parse_nt_against_word_range(spec_global_variable_NTM, w1, w2, NULL, NULL)) {
specification *val = most_recent_result_p;
return RETRIEVE_FROM_SPEC(val, nonlocal_variable);
}
return NULL;
}
#line 181 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__translates(int w1, int w2, parse_node *p2) {
nonlocal_variable *nlv = Data__NonlocalVariables__parse(w1, w2);
if ((nlv == NULL) || (nlv->scope)) {
LOG("Tried $W\n", w1, w2);
Problems__sentence_problem(_P_(C20NonQuantityTranslated),
"this is not the name of a variable",
"or at any rate not one global in scope.");
return;
}
if (nlv->nlv_name_translated) {
Problems__sentence_problem(_P_(C20QuantityTranslatedAlready),
"this variable has already been translated",
"so there must be some duplication somewhere.");
return;
}
nlv->nlv_name_translated = TRUE;
char *name = Text__word_text(p2->word_ref1);
Data__NonlocalVariables__set_I6_identifier(nlv, name, name);
LOGIF(VARIABLE_CREATIONS,
"Translated variable: $Z as %s\n", nlv, Text__word_text(p2->word_ref1));
}
#line 210 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__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 222 "inform7/Chapter 20/Nonlocal Variables.w"
char *Data__NonlocalVariables__identifier(nonlocal_variable *nlv) {
if (nlv->nlv_as_rvalue[0] == 0) allocate_nlv_storage();
return nlv->nlv_as_rvalue;
}
char *Data__NonlocalVariables__lvalue_identifier(nonlocal_variable *nlv) {
if (nlv->nlv_as_lvalue[0] == 0) allocate_nlv_storage();
return nlv->nlv_as_lvalue;
}
#line 236 "inform7/Chapter 20/Nonlocal Variables.w"
void allocate_nlv_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);
Data__NonlocalVariables__set_I6_identifier(var, name, name);
var->position_in_variables_array = k++;
}
}
#line 256 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__set_write_schema(nonlocal_variable *nlv, char *sch) {
nlv->nlv_write_schema = sch;
}
char *Data__NonlocalVariables__get_write_schema(nonlocal_variable *nlv) {
Data__NonlocalVariables__warn_about_change(nlv);
if (nlv == NULL) return NULL;
return nlv->nlv_write_schema;
}
void Data__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__sentence_problem(_P_(C20CantChangeScore),
"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 286 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__Subjects__get_name_text(inference_subject *from, int *w1, int *w2) {
nonlocal_variable *nlv = World__Subjects__as_nlv(from);
*w1 = nlv->word_ref1; *w2 = nlv->word_ref2;
}
general_pointer Data__NonlocalVariables__Subjects__new_permission_granted(inference_subject *from) {
return NULL_GENERAL_POINTER;
}
void Data__NonlocalVariables__Subjects__make_adj_const_domain(inference_subject *infs,
instance *nc, property *prn) {
}
void Data__NonlocalVariables__Subjects__complete_model(inference_subject *infs) {
}
void Data__NonlocalVariables__Subjects__check_model(inference_subject *infs) {
}
void Data__NonlocalVariables__Subjects__write_element_of_condition(inference_subject *infs, char *cond) {
internal_error("NLV in runtime match condition");
}
void Data__NonlocalVariables__Subjects__compile(OUTPUT_STREAM, inference_subject *infs) {
}
inference_subject *Data__NonlocalVariables__get_knowledge(nonlocal_variable *nlv) {
return nlv->nlv_knowledge;
}
#line 320 "inform7/Chapter 20/Nonlocal Variables.w"
int Data__NonlocalVariables__Subjects__compile_all(OUTPUT_STREAM) {
allocate_nlv_storage(); /* in case this hasn't happened already */
{
#line 355 "inform7/Chapter 20/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) &&
(Data__NonlocalVariables__has_initial_value_set(nlv)))
{
#line 366 "inform7/Chapter 20/Nonlocal Variables.w"
current_sentence = Data__NonlocalVariables__origin_of_initial_value(nlv);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, nlv->word_ref1, nlv->word_ref2);
Problems__quote_text(3, nlv->nlv_as_lvalue);
Problems__handmade_problem(_P_(C20InaccessibleVariable));
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 361 "inform7/Chapter 20/Nonlocal Variables.w"
;
}
#line 322 "inform7/Chapter 20/Nonlocal Variables.w"
;
nonlocal_variable *nlv;
LOOP_OVER(nlv, nonlocal_variable) {
current_sentence = Data__NonlocalVariables__origin_of_initial_value(nlv);
if (Data__NonlocalVariables__has_initial_value_set(nlv))
Parser__Assertions__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);
Data__NonlocalVariables__compile_initial_value(OUT, nlv);
END_COMPILATION_MODE;
WRITE(") ! %d ", nlv->allocation_id);
Formats__Inform6__compile_as_comment(OUT,
nlv->word_ref1, nlv->word_ref2);
WRITE("\n");
k++;
}
if (k < 2) WRITE(" NULL NULL");
WRITE(";\n");
return TRUE;
}
#line 383 "inform7/Chapter 20/Nonlocal Variables.w"
specification *Data__NonlocalVariables__get_initial_value(nonlocal_variable *nlv) {
inference *inf;
inference_subject *infs = Data__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__Unknown__new(-1, -1);
}
parse_node *Data__NonlocalVariables__origin_of_initial_value(nonlocal_variable *nlv) {
inference *inf;
inference_subject *infs = Data__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 Data__NonlocalVariables__has_initial_value_set(nonlocal_variable *nlv) {
if ((nlv) && (Data__NonlocalVariables__origin_of_initial_value(nlv))) return TRUE;
return FALSE;
}
#line 409 "inform7/Chapter 20/Nonlocal Variables.w"
int Data__NonlocalVariables__is_global(nonlocal_variable *nlv) {
if (nlv->scope) return FALSE;
return TRUE;
}
#line 419 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__set_kind(nonlocal_variable *nlv, kind *K) {
if (nlv == NULL) internal_error("set kind for null variable");
nlv->nlv_kind = K;
}
kind *Data__NonlocalVariables__kind(nonlocal_variable *nlv) {
if (nlv == NULL) return NULL;
return nlv->nlv_kind;
}
#line 432 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable *Data__NonlocalVariables__temporary(char *I6_form, kind *K) {
Data__NonlocalVariables__set_I6_identifier(i6_glob_VAR, I6_form, I6_form);
Data__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 *Data__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] = new_nonlocal_variable(-1, -1, K_object, NULL);
Data__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 459 "inform7/Chapter 20/Nonlocal Variables.w"
int Data__NonlocalVariables__treat_as_plain_text_word(nonlocal_variable *nlv) {
inference *inf;
inference_subject *infs = Data__NonlocalVariables__get_knowledge(nlv);
POSITIVE_KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_variable_initial_value) {
return World__Inferences__set_property_value_kind(inf, K_text)->word_ref1;
}
return -1;
}
#line 473 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__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 Data__NonlocalVariables__make_initalisable(nonlocal_variable *nlv) {
nlv->var_is_initialisable_anyway = TRUE;
}
int Data__NonlocalVariables__is_constant(nonlocal_variable *nlv) {
if (nlv == NULL) internal_error("no such var");
return nlv->constant_at_run_time;
}
int Data__NonlocalVariables__must_be_constant(nonlocal_variable *nlv) {
if (nlv->constant_at_run_time) {
Problems__sentence_problem(_P_(C20CantChangeConstants),
"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 503 "inform7/Chapter 20/Nonlocal Variables.w"
specification *Data__NonlocalVariables__substitute_constants(specification *spec) {
int depth = 0;
while (TRUE) {
if (depth++ > 20) internal_error("ill-founded constants");
nonlocal_variable *nlv = Specifications__Storage__get_nonlocal_variable_if_any(spec);
if ((nlv) && (nlv->constant_at_run_time)) {
specification *sspec = Data__NonlocalVariables__get_initial_value(nlv);
if (Specifications__is_UNKNOWN(sspec) == FALSE) { spec = sspec; continue; }
}
break;
}
return spec;
}
#line 523 "inform7/Chapter 20/Nonlocal Variables.w"
inference_subject *Data__NonlocalVariables__get_alias(nonlocal_variable *nlv) {
if (nlv) {
specification *val = Data__NonlocalVariables__get_initial_value(nlv);
inference_subject *vals = World__Subjects__from_specification(val);
if (vals) return vals;
return nlv->alias_to_infs;
}
return NULL;
}
void Data__NonlocalVariables__set_alias(nonlocal_variable *nlv, inference_subject *infs) {
nlv->alias_to_infs = infs;
}
#line 549 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__compile_initial_value(OUTPUT_STREAM, nonlocal_variable *nlv) {
TEMPORARY_STREAM;
compile_nonlocal_variable_initial_inner(TEMP, nlv);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
void compile_nonlocal_variable_initial_inner(OUTPUT_STREAM, nonlocal_variable *nlv) {
specification *val =
Data__NonlocalVariables__substitute_constants(
Data__NonlocalVariables__get_initial_value(
nlv));
if (Specifications__is_UNKNOWN(val)) {
current_sentence = nlv->nlv_created_at;
{
#line 575 "inform7/Chapter 20/Nonlocal Variables.w"
if (Kinds__compile_default_value(OUT, nlv->nlv_kind,
nlv->word_ref1, nlv->word_ref2, "variable") == FALSE) {
int w1, w2;
Kinds__get_name(nlv->nlv_kind, &w1, &w2, FALSE);
Problems__quote_words(1, nlv->word_ref1, nlv->word_ref2);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C20EmptyDataType));
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 563 "inform7/Chapter 20/Nonlocal Variables.w"
} else {
current_sentence = Data__NonlocalVariables__origin_of_initial_value(nlv);
if (Specifications__Storage__get_storage_form(val) == NONLOCAL_VARIABLE_SPC)
{
#line 591 "inform7/Chapter 20/Nonlocal Variables.w"
nonlocal_variable *the_other = RETRIEVE_FROM_SPEC(val, nonlocal_variable);
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_words(2, nlv->word_ref1, nlv->word_ref2);
Problems__quote_kind(3, nlv->nlv_kind);
Problems__handmade_problem(_P_(C20InitialiseQ2));
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_words(2, nlv->word_ref1, nlv->word_ref2);
Problems__quote_kind(3, nlv->nlv_kind);
Problems__quote_words(4, the_other->word_ref1, the_other->word_ref2);
Problems__quote_kind(5, the_other->nlv_kind);
Problems__handmade_problem(_P_(C20InitialiseQ1));
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 567 "inform7/Chapter 20/Nonlocal Variables.w"
else Specifications__compile_constant_to_kind(OUT, val, nlv->nlv_kind);
}
}
#line 629 "inform7/Chapter 20/Nonlocal Variables.w"
int value_understood_variable_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 631 "inform7/Chapter 20/Nonlocal Variables.w"
#line 635 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__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 ((nlv->word_ref1 >= 0) && (Data__NonlocalVariables__is_global(nlv))) {
if (parse_nt_against_word_range(value_understood_variable_name_NTM, nlv->word_ref1, nlv->word_ref2, NULL, NULL))
{
#line 653 "inform7/Chapter 20/Nonlocal Variables.w"
if (understood_note_given == FALSE) {
understood_note_given = TRUE;
INDEX("<i>kind</i> understood - <i>value</i><br>\n");
}
}
#line 644 "inform7/Chapter 20/Nonlocal Variables.w"
else
{
#line 661 "inform7/Chapter 20/Nonlocal Variables.w"
definition_area =
Parser__Sentences__Headings__heading_of(Text__word_location(nlv->word_ref1));
if (Parser__Sentences__Headings__indexed(definition_area) == FALSE) continue;
if (definition_area != current_area) {
int x1, x2;
Parser__Sentences__Headings__get_text(definition_area, &x1, &x2);
INDEX("<p>");
if (x1 >= 0) Code__Phrases__index_definition_area(x1, x2, FALSE);
}
current_area = definition_area;
Data__NonlocalVariables__index_single(nlv);
INDEX("<br>\n");
}
#line 646 "inform7/Chapter 20/Nonlocal Variables.w"
;
}
}
#line 677 "inform7/Chapter 20/Nonlocal Variables.w"
void Data__NonlocalVariables__index_single(nonlocal_variable *nlv) {
Text__print_raw_text_to_stream(nlv->word_ref1, nlv->word_ref2, ifl);
Index__link(nlv->word_ref1);
if (nlv->var_documentation_symbol_wn >= 0) {
Index__doc_link(Text__word_raw_text(nlv->var_documentation_symbol_wn));
}
INDEX(" - <i>");
Kinds__Textual__write(ifl, nlv->nlv_kind);
INDEX("</i>");
}
#line 26 "inform7/Chapter 20/Interactive Fiction ID.w"
char uuid_text[MAX_UUID_LENGTH];
int uuid_read = -1;
char *Plugins__Bibliographic__read_uuid(void) {
FILE *xf; char *fn;
int i=0; int c;
if (uuid_read >= 0) return uuid_text;
uuid_read = 0;
fn = Files__Filenames__top_level(UUID_LEAFNAME);
xf = Platform__iso_fopen(fn, "r");
if (xf == NULL) {
uuid_text[0] = 0; /* the UUID is the empty string if the file is missing */
return uuid_text;
}
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 57 "inform7/Chapter 20/Interactive Fiction ID.w"
void Plugins__Bibliographic__UUID_ARRAY_array(OUTPUT_STREAM) {
int i;
char *uuid = Plugins__Bibliographic__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 20/Bibliographic Data.w"
void Plugins__Bibliographic__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_VARIABLE_NOTIFY, bibliographic_new_variable_notify);
}
#line 52 "inform7/Chapter 20/Bibliographic Data.w"
int notable_bibliographic_variables_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 60 "inform7/Chapter 20/Bibliographic Data.w"
#line 72 "inform7/Chapter 20/Bibliographic Data.w"
int bibliographic_new_variable_notify(nonlocal_variable *q) {
if (parse_nt_against_word_range(notable_bibliographic_variables_NTM, q->word_ref1, q->word_ref2, 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;
}
Data__NonlocalVariables__make_constant(q, TRUE);
}
return FALSE;
}
#line 92 "inform7/Chapter 20/Bibliographic Data.w"
int titling_line_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 20/Bibliographic Data.w"
int plain_titling_line_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 20/Bibliographic Data.w"
#line 105 "inform7/Chapter 20/Bibliographic Data.w"
natural_language *Plugins__Bibliographic__scan_language(parse_node *PN) {
int w1 = PN->word_ref1, w2 = PN->word_ref2;
if (parse_nt_against_word_range(titling_line_NTM, w1, w2, NULL, NULL)) return most_recent_result_p;
return NULL;
}
#line 117 "inform7/Chapter 20/Bibliographic Data.w"
sentence_handler BIBLIOGRAPHIC_SH_handler =
{ BIBLIOGRAPHIC_NT, -1, 2, bibliographic_data };
void bibliographic_data(parse_node *PN) {
if (parse_nt_against_word_range(titling_line_NTM, PN->word_ref1, PN->word_ref2, NULL, NULL)) {
int t1 = -1, t2 = -1, aw1 = -1, aw2 = -1;
GET_RW(plain_titling_line_NTM, 1, t1, t2);
if (most_recent_result) GET_RW(plain_titling_line_NTM, 2, aw1, aw2);
if ((story_title_VAR) && (story_author_VAR)) {
{
#line 141 "inform7/Chapter 20/Bibliographic Data.w"
specification *the_title;
if (parse_nt_against_word_range(spec_value_NTM, t1, t2, NULL, NULL)) the_title = most_recent_result_p;
else the_title = Specifications__Unknown__new(t1, t2);
Parser__Assertions__initialise_global_variable(story_title_VAR, the_title);
Data__Strings__suppress_quote_expansion(the_title->word_ref1);
}
#line 126 "inform7/Chapter 20/Bibliographic Data.w"
;
if (aw1 >= 0)
{
#line 155 "inform7/Chapter 20/Bibliographic Data.w"
char author_buffer[1024];
if (parse_nt_against_word_range(quoted_text_NTM, aw1, aw2, NULL, NULL) == FALSE) {
author_buffer[0] = '\"';
Text__print_raw_text_to_string_truncated(aw1, aw2, author_buffer+1, 1020);
int i;
for (i=1; author_buffer[i]; i++)
if (author_buffer[i] == '\"') author_buffer[i] = '\'';
sprintf(author_buffer+Platform__strlen(author_buffer), "\" ");
Text__feed_into_lexer(author_buffer, FALSE, NULL);
aw1 = lexer_feed_w1; aw2 = lexer_feed_w2;
}
specification *the_author;
if (parse_nt_against_word_range(spec_value_NTM, aw1, aw1, NULL, NULL)) the_author = most_recent_result_p;
else the_author = Specifications__Unknown__new(aw1, aw1);
Parser__Assertions__initialise_global_variable(story_author_VAR, the_author);
}
#line 127 "inform7/Chapter 20/Bibliographic Data.w"
;
}
} else {
Problems__sentence_problem(_P_(C20BadTitleSentence),
"the initial bibliographic sentence can only be a title in double-quotes",
"possibly followed with 'by' and the name of the author.");
}
}
#line 177 "inform7/Chapter 20/Bibliographic Data.w"
int Plugins__Bibliographic__story_author_is(char *p) {
if ((story_author_VAR) &&
(Data__NonlocalVariables__has_initial_value_set(story_author_VAR))) {
specification *spec = Data__NonlocalVariables__get_initial_value(story_author_VAR);
Specifications__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__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 199 "inform7/Chapter 20/Bibliographic Data.w"
sentence_handler EPISODE_SH_handler =
{ SENTENCE_NT, EPISODE_VB, 1, set_episode_data };
#line 214 "inform7/Chapter 20/Bibliographic Data.w"
int episode_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 221 "inform7/Chapter 20/Bibliographic Data.w"
*X = -1;
Problems__sentence_problem(_P_(C20BadEpisode),
"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 216 "inform7/Chapter 20/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 217 "inform7/Chapter 20/Bibliographic Data.w"
#line 233 "inform7/Chapter 20/Bibliographic Data.w"
void set_episode_data(parse_node *pn) {
int w1, w2;
w1 = pn->down->next->next->word_ref1; w2 = pn->down->next->next->word_ref2;
parse_nt_against_word_range(episode_sentence_object_NTM, w1, w2, NULL, NULL);
if (most_recent_result >= 0) {
episode_number = most_recent_result;
Text__dequote_word(series_NTMV);
series_name = Text__word_text(series_NTMV);
}
}
#line 249 "inform7/Chapter 20/Bibliographic Data.w"
void Plugins__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 268 "inform7/Chapter 20/Bibliographic Data.w"
Data__NonlocalVariables__treat_as_plain_text_word(story_title_VAR);
WRITE("Global Story = ");
if (Data__NonlocalVariables__has_initial_value_set(story_title_VAR))
Data__NonlocalVariables__compile_initial_value(OUT, story_title_VAR);
else
Data__Strings__compile_literal_from_text(OUT, "\"Welcome\"");
WRITE(";\n");
}
#line 254 "inform7/Chapter 20/Bibliographic Data.w"
;
if (story_headline_VAR)
{
#line 279 "inform7/Chapter 20/Bibliographic Data.w"
WRITE("Constant Headline ");
if (Data__NonlocalVariables__has_initial_value_set(story_headline_VAR)) {
Data__NonlocalVariables__treat_as_plain_text_word(story_headline_VAR);
Data__NonlocalVariables__compile_initial_value(OUT, story_headline_VAR);
} else {
Data__Strings__compile_literal_from_text(OUT, "\"An Interactive Fiction\"");
}
WRITE(";\n");
}
#line 255 "inform7/Chapter 20/Bibliographic Data.w"
;
if (story_author_VAR)
{
#line 291 "inform7/Chapter 20/Bibliographic Data.w"
if (Data__NonlocalVariables__has_initial_value_set(story_author_VAR)) {
WRITE("Constant Story_Author ");
Data__NonlocalVariables__treat_as_plain_text_word(story_author_VAR);
Data__NonlocalVariables__compile_initial_value(OUT, story_author_VAR);
WRITE(";\n");
}
}
#line 256 "inform7/Chapter 20/Bibliographic Data.w"
;
if (story_release_number_VAR)
{
#line 301 "inform7/Chapter 20/Bibliographic Data.w"
if (Data__NonlocalVariables__has_initial_value_set(story_release_number_VAR)) {
WRITE("Release ");
Data__NonlocalVariables__compile_initial_value(OUT, story_release_number_VAR);
WRITE(";\n");
}
}
#line 257 "inform7/Chapter 20/Bibliographic Data.w"
;
{
#line 312 "inform7/Chapter 20/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 258 "inform7/Chapter 20/Bibliographic Data.w"
;
END_COMPILATION_MODE;
encode_constant_text_bibliographically = FALSE;
}
#line 321 "inform7/Chapter 20/Bibliographic Data.w"
void Plugins__Bibliographic__index_library_card(void) {
INDEX("<p>");
Index__anchor("LCARD");
Formats__HTML__begin_html_table(ifl, "*bg_images/indexcard.png", FALSE, 0, 3, 3, 0, 0);
library_card_entry("Story title", story_title_VAR, "Untitled");
library_card_entry("Story author", story_author_VAR, "Anonymous");
library_card_entry("Story headline", story_headline_VAR, "An Interactive Fiction");
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);
library_card_entry("Episode", NULL, episode_text);
}
library_card_entry("Release number", story_release_number_VAR, "1");
library_card_entry("Story creation year", story_creation_year_VAR, "(This year)");
library_card_entry("Language of play", NULL, Text__Languages__get_name(language_of_play));
library_card_entry("IFID number", NULL, uuid_text);
library_card_entry("Story description", story_description_VAR, "None");
Formats__HTML__end_html_table(ifl);
INDEX("</p>");
}
#line 346 "inform7/Chapter 20/Bibliographic Data.w"
void 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\">";
Formats__HTML__first_html_column_nowrap(ifl, 0, NULL);
INDEX("%s%s</font>", font, field);
Formats__HTML__next_html_column(ifl, 0);
INDEX("%s<b>", font);
index_bibliographic_variable(nlv, t);
INDEX("</b></font>");
Formats__HTML__end_html_row(ifl);
}
#line 363 "inform7/Chapter 20/Bibliographic Data.w"
void Plugins__Bibliographic__contents_heading(void) {
if ((story_title_VAR == NULL) || (story_author_VAR == NULL))
INDEX("Contents");
else {
index_bibliographic_variable(story_title_VAR, "Untitled");
INDEX(" by ");
index_bibliographic_variable(story_author_VAR, "Anonymous");
}
}
#line 376 "inform7/Chapter 20/Bibliographic Data.w"
void 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) && (Data__NonlocalVariables__has_initial_value_set(nlv))) {
Data__Strings__compile_literal(ifl,
Data__NonlocalVariables__treat_as_plain_text_word(nlv));
} else {
INDEX("%s", t);
}
END_COMPILATION_MODE;
divert_constant_text_bibliographically = FALSE;
}
#line 65 "inform7/Chapter 20/Release Instructions.w"
int release_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 89 "inform7/Chapter 20/Release Instructions.w"
*X = BOOKLET_PAYLOAD; /* to recover harmlessly */
Problems__quote_words_as_source(1, w1, w2);
Problems__handmade_problem(_P_(C20NoSuchPublicRelease));
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 20/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 = AUXILIARY_FILE_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = HIDDEN_FILE_IN_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = HIDDEN_FILE_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *X = CSS_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10: *X = JAVASCRIPT_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11: *X = BOOKLET_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12: *X = POSTCARD_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13: *X = WEBSITE_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14: *X = SEPARATE_FIGURES_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15: *X = SEPARATE_SOUNDS_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 16: *X = THEMED_WEBSITE_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 17: *X = INTERPRETER_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 18: *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 85 "inform7/Chapter 20/Release Instructions.w"
#line 103 "inform7/Chapter 20/Release Instructions.w"
int privacy_indicator_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 106 "inform7/Chapter 20/Release Instructions.w"
int exposed_innards_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 111 "inform7/Chapter 20/Release Instructions.w"
#line 115 "inform7/Chapter 20/Release Instructions.w"
sentence_handler RELEASE_SH_handler =
{ SENTENCE_NT, RELEASE_VB, 1, handle_release_declaration };
void handle_release_declaration(parse_node *p) {
handle_release_declaration_inner(p->down->next);
}
void handle_release_declaration_inner(parse_node *p) {
if (Parser__Nodes__type(p) == AND_NT) {
handle_release_declaration_inner(p->down);
handle_release_declaration_inner(p->down->next);
return;
}
current_sentence = p;
int w1 = p->word_ref1, w2 = p->word_ref2;
if (parse_nt_against_word_range(release_sentence_object_NTM, w1, w2, NULL, NULL))
{
#line 159 "inform7/Chapter 20/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:
if (Code__VirtualMachines__is_16_bit() == FALSE) {
Problems__sentence_problem(_P_(BelievedImpossible), /* not usefully testable */
"existing story files can only be used with the Z-machine",
"not with the Glulx setting.");
return;
}
existing_story_file = TRUE;
break;
case AUXILIARY_FILE_PAYLOAD: {
int leafname_wn, desc_wn;
GET_RW(release_sentence_object_NTM, 1, desc_wn, desc_wn);
GET_RW(release_sentence_object_NTM, 2, leafname_wn, leafname_wn);
Text__dequote_word(leafname_wn);
Text__dequote_word(desc_wn);
Plugins__Bibliographic__create_aux_file(
Text__word_text(leafname_wn), Text__word_text(desc_wn),
"--", payload);
break;
}
case CSS_PAYLOAD: case JAVASCRIPT_PAYLOAD: case HIDDEN_FILE_PAYLOAD: {
int leafname_wn;
GET_RW(release_sentence_object_NTM, 1, leafname_wn, leafname_wn);
Text__dequote_word(leafname_wn);
Plugins__Bibliographic__create_aux_file(
Text__word_text(leafname_wn), "--", "--", payload);
break;
}
case HIDDEN_FILE_IN_PAYLOAD: {
int leafname_wn, folder_wn;
GET_RW(release_sentence_object_NTM, 1, leafname_wn, leafname_wn);
GET_RW(release_sentence_object_NTM, 2, folder_wn, folder_wn);
Text__dequote_word(leafname_wn);
Text__dequote_word(folder_wn);
Plugins__Bibliographic__create_aux_file(
Text__word_text(leafname_wn), "--",
Text__word_text(folder_wn), 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: {
int theme_name_wn;
GET_RW(release_sentence_object_NTM, 1, theme_name_wn, theme_name_wn);
Text__dequote_word(theme_name_wn);
website_template_leafname = Text__word_text(theme_name_wn);
release_website = TRUE;
break;
}
case INTERPRETER_PAYLOAD:
release_interpreter = TRUE; release_website = TRUE;
break;
case THEMED_INTERPRETER_PAYLOAD: {
int theme_name_wn;
GET_RW(release_sentence_object_NTM, 1, theme_name_wn, theme_name_wn);
Text__dequote_word(theme_name_wn);
interpreter_template_leafname = Text__word_text(theme_name_wn);
release_interpreter = TRUE; release_website = TRUE;
break;
}
case SEPARATE_FIGURES_PAYLOAD:
Plugins__Figures__write_copy_commands();
break;
case SEPARATE_SOUNDS_PAYLOAD:
Plugins__Sounds__write_copy_commands();
break;
}
}
#line 132 "inform7/Chapter 20/Release Instructions.w"
else
{
#line 250 "inform7/Chapter 20/Release Instructions.w"
Problems__quote_source(1, p);
Problems__handmade_problem(_P_(C20ReleaseAlong));
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 134 "inform7/Chapter 20/Release Instructions.w"
;
}
#line 263 "inform7/Chapter 20/Release Instructions.w"
auxiliary_file *Plugins__Bibliographic__create_aux_file(char *leafname,
char *desc, char *subfolder, int payload) {
auxiliary_file *af = CREATE(auxiliary_file);
af->leafname_in_materials_folder = leafname;
af->brief_description = desc;
af->foldername_in_release_folder = subfolder;
af->from_payload = payload;
return af;
}
#line 281 "inform7/Chapter 20/Release Instructions.w"
void Plugins__Bibliographic__write_ifiction_and_blurb(void) {
{
#line 301 "inform7/Chapter 20/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 316 "inform7/Chapter 20/Release Instructions.w"
if ((materials_folder[0] == 0) ||
(Platform__platform_specific_mkdir(materials_folder) == FALSE)) {
Problems__release_problem(_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",
materials_folder);
return;
}
}
#line 308 "inform7/Chapter 20/Release Instructions.w"
;
{
#line 330 "inform7/Chapter 20/Release Instructions.w"
char release_folder[MAX_FILENAME_LENGTH];
sprintf(release_folder, "%s%cRelease", materials_folder, FOLDER_SEPARATOR);
if (Platform__platform_specific_mkdir(release_folder) == FALSE) {
Problems__release_problem(_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",
release_folder);
return;
}
auxiliary_file *af;
LOOP_OVER(af, auxiliary_file)
if (strcmp(af->foldername_in_release_folder, "--") != 0) {
char aux_folder[MAX_FILENAME_LENGTH];
sprintf(aux_folder, "%s%c%s", release_folder, FOLDER_SEPARATOR,
af->foldername_in_release_folder);
if (Platform__platform_specific_mkdir(aux_folder) == FALSE) {
Problems__release_problem(_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",
aux_folder);
return;
}
}
}
#line 309 "inform7/Chapter 20/Release Instructions.w"
;
if (release_interpreter)
{
#line 361 "inform7/Chapter 20/Release Instructions.w"
char interpreter_folder[MAX_FILENAME_LENGTH];
sprintf(interpreter_folder, "%s%cRelease%cinterpreter",
materials_folder, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
if (Platform__platform_specific_mkdir(interpreter_folder) == FALSE) {
Problems__release_problem(_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",
interpreter_folder);
return;
}
}
#line 310 "inform7/Chapter 20/Release Instructions.w"
;
}
}
#line 282 "inform7/Chapter 20/Release Instructions.w"
;
int cover_picture_number = (release_cover)?1:0;
char *cover_art_format = NULL;
unsigned int width = 0, height = 0;
{
#line 378 "inform7/Chapter 20/Release Instructions.w"
if (release_cover) {
current_sentence = cover_filename_sentence;
cover_art_format = "";
char cover_filename[MAX_FILENAME_LENGTH];
sprintf(cover_filename, "%s%cCover.jpg", materials_folder, FOLDER_SEPARATOR);
FILE *COVER_FILE = Platform__iso_fopen(cover_filename, "rb" );
if (COVER_FILE)
{
#line 397 "inform7/Chapter 20/Release Instructions.w"
cover_art_format = "jpg";
int rv = Files__Formats__JPEG__get_dimensions(COVER_FILE, &width, &height);
fclose(COVER_FILE);
if (rv == FALSE) {
Problems__release_problem(_P_(Untestable),
"The cover image seems not to be a JPEG despite the name",
cover_filename);
return;
}
}
#line 384 "inform7/Chapter 20/Release Instructions.w"
else {
sprintf(cover_filename, "%s%cCover.png", materials_folder, FOLDER_SEPARATOR);
COVER_FILE = Platform__iso_fopen(cover_filename, "rb" );
if (COVER_FILE)
{
#line 410 "inform7/Chapter 20/Release Instructions.w"
cover_art_format = "png";
int rv = Files__Formats__PNG__get_dimensions(COVER_FILE, &width, &height);
fclose(COVER_FILE);
if (rv == FALSE) {
Problems__release_problem(_P_(Untestable),
"The cover image seems not to be a PNG despite the name",
cover_filename);
return;
}
}
#line 388 "inform7/Chapter 20/Release Instructions.w"
else
{
#line 423 "inform7/Chapter 20/Release Instructions.w"
Problems__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 389 "inform7/Chapter 20/Release Instructions.w"
;
}
{
#line 433 "inform7/Chapter 20/Release Instructions.w"
if ((width < 120) || (width > 1200) || (height < 120) || (height > 1200)) {
Problems__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__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 391 "inform7/Chapter 20/Release Instructions.w"
;
}
}
#line 287 "inform7/Chapter 20/Release Instructions.w"
;
char header[LENGTH_OF_STORY_FILE_HEADER]; /* a sequence of bytes, not a C string */
if (existing_story_file)
{
#line 452 "inform7/Chapter 20/Release Instructions.w"
if (this_is_a_release_compile == FALSE)
{
#line 477 "inform7/Chapter 20/Release Instructions.w"
Problems__unlocated_problem(_P_(C20UnreleasedRelease),
"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.)");
}
#line 453 "inform7/Chapter 20/Release Instructions.w"
;
int i;
char story_filename[2*MAX_FILENAME_LENGTH];
if (story_filename_extension == NULL)
sprintf(story_filename, "%s%cstory.z5",
materials_folder, FOLDER_SEPARATOR);
else
sprintf(story_filename, "%s%cstory.%s",
materials_folder, FOLDER_SEPARATOR, story_filename_extension);
FILE *STORYF = Platform__iso_fopen(story_filename, "rb");
if (STORYF == NULL) {
Problems__Fatal__issue2("Unable to find the promised existing story file",
story_filename);
}
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 290 "inform7/Chapter 20/Release Instructions.w"
if (problem_count == 0)
{
#line 492 "inform7/Chapter 20/Release Instructions.w"
divert_constant_text_bibliographically = TRUE;
{
#line 501 "inform7/Chapter 20/Release Instructions.w"
STREAM xf_struct; STREAM *xf = &xf_struct;
char *fn = Files__Filenames__top_level(METADATA_LEAFNAME);
if (STREAM_OPEN_TO_FILE(xf, fn, UTF8_ENC) == FALSE)
Problems__Fatal__issue2("Can't open metadata file", fn);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(COMPILE_TEXT_TO_XML_CMODE);
write_ifiction_record(xf, header, cover_picture_number, cover_art_format, height, width);
END_COMPILATION_MODE;
STREAM_CLOSE(xf);
}
#line 493 "inform7/Chapter 20/Release Instructions.w"
;
{
#line 514 "inform7/Chapter 20/Release Instructions.w"
STREAM xf_struct; STREAM *xf = &xf_struct;
char *fn = Files__Filenames__top_level(BLURB_LEAFNAME);
if (STREAM_OPEN_TO_FILE(xf, fn, UTF8_ENC) == FALSE)
Problems__Fatal__issue2("Can't open blurb file", fn);
write_release_blurb(xf, materials_folder, cover_picture_number, cover_art_format);
STREAM_CLOSE(xf);
}
#line 494 "inform7/Chapter 20/Release Instructions.w"
;
{
#line 524 "inform7/Chapter 20/Release Instructions.w"
STREAM xf_struct; STREAM *xf = &xf_struct;
char *fn = Files__Filenames__top_level(MANIFEST_LEAFNAME);
if (STREAM_OPEN_TO_FILE(xf, fn, UTF8_ENC) == FALSE)
Problems__Fatal__issue2("Can't open manifest file", fn);
Plugins__Figures__write_picture_manifest(xf, release_cover);
STREAM_CLOSE(xf);
}
#line 495 "inform7/Chapter 20/Release Instructions.w"
;
divert_constant_text_bibliographically = FALSE;
}
#line 292 "inform7/Chapter 20/Release Instructions.w"
;
}
#line 534 "inform7/Chapter 20/Release Instructions.w"
void 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 549 "inform7/Chapter 20/Release Instructions.w"
char *story_format = "zcode";
if ((story_filename_extension) &&
(strcmp(story_filename_extension, "ulx") == 0))
story_format = "glulx";
{
#line 569 "inform7/Chapter 20/Release Instructions.w"
WRITE("<identification>\n"); INDENT;
WRITE("<ifid>%s</ifid>\n", Plugins__Bibliographic__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 554 "inform7/Chapter 20/Release Instructions.w"
;
{
#line 586 "inform7/Chapter 20/Release Instructions.w"
WRITE("<bibliographic>\n"); INDENT;
WRITE("<title>");
if (write_var_to_XML(OUT, story_title_VAR, FALSE) == FALSE) WRITE("Untitled");
WRITE("</title>\n");
WRITE("<author>");
if (write_var_to_XML(OUT, story_author_VAR, FALSE) == FALSE) WRITE("Anonymous");
WRITE("</author>\n");
WRITE("<headline>");
if (write_var_to_XML(OUT, story_headline_VAR, FALSE) == FALSE)
WRITE("An Interactive Fiction");
WRITE("</headline>\n");
WRITE("<genre>");
if (write_var_to_XML(OUT, story_genre_VAR, FALSE) == FALSE) WRITE("Fiction");
WRITE("</genre>\n");
WRITE("<firstpublished>");
if (write_var_to_XML(OUT, story_creation_year_VAR, FALSE) == FALSE)
WRITE("%d", (the_present->tm_year)+1900);
WRITE("</firstpublished>\n");
if (Data__NonlocalVariables__has_initial_value_set(story_description_VAR)) {
WRITE("<description>");
write_var_to_XML(OUT, story_description_VAR, TRUE);
WRITE("</description>\n");
}
WRITE("<language>");
Text__Languages__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 555 "inform7/Chapter 20/Release Instructions.w"
;
if (NUMBER_CREATED(auxiliary_file) > 0)
{
#line 622 "inform7/Chapter 20/Release Instructions.w"
auxiliary_file *af;
WRITE("<resources>\n"); INDENT;
LOOP_OVER(af, auxiliary_file) {
WRITE("<auxiliary>\n"); INDENT;
WRITE("<leafname>");
Formats__HTML__write_xml_safe_text(OUT, af->leafname_in_materials_folder);
WRITE("</leafname>\n");
if (af->brief_description) {
WRITE("<description>");
Formats__HTML__write_xml_safe_text(OUT, af->brief_description);
WRITE("</description>\n");
}
OUTDENT; WRITE("</auxiliary>\n");
}
OUTDENT; WRITE("</resources>\n");
}
#line 557 "inform7/Chapter 20/Release Instructions.w"
;
if (release_cover)
{
#line 642 "inform7/Chapter 20/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 = Plugins__Figures__description_of_cover_art();
if (cover_alt_text >= 0) {
LOG("CAT $W\n", cover_alt_text, cover_alt_text);
Text__dequote_word(cover_alt_text);
desc = Text__word_text(cover_alt_text);
}
WRITE("<description>%s</description>\n", desc);
OUTDENT; WRITE("</cover>\n");
}
#line 559 "inform7/Chapter 20/Release Instructions.w"
;
{
#line 658 "inform7/Chapter 20/Release Instructions.w"
WRITE("<releases>\n"); INDENT;
WRITE("<attached>\n"); INDENT;
WRITE("<release>\n"); INDENT;
if (existing_story_file)
{
#line 674 "inform7/Chapter 20/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 661 "inform7/Chapter 20/Release Instructions.w"
else
{
#line 701 "inform7/Chapter 20/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) &&
(Data__NonlocalVariables__has_initial_value_set(story_release_number_VAR))) {
WRITE("<version>");
Data__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 662 "inform7/Chapter 20/Release Instructions.w"
;
OUTDENT; WRITE("</release>\n");
OUTDENT; WRITE("</attached>\n");
OUTDENT; WRITE("</releases>\n");
}
#line 560 "inform7/Chapter 20/Release Instructions.w"
;
{
#line 715 "inform7/Chapter 20/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 561 "inform7/Chapter 20/Release Instructions.w"
;
WRITE("<%s>\n", story_format); INDENT;
{
#line 726 "inform7/Chapter 20/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) &&
(Data__NonlocalVariables__has_initial_value_set(story_release_number_VAR))) {
WRITE("<release>");
Data__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 563 "inform7/Chapter 20/Release Instructions.w"
;
OUTDENT; WRITE("</%s>\n", story_format);
}
#line 541 "inform7/Chapter 20/Release Instructions.w"
;
OUTDENT; WRITE("</story>\n");
OUTDENT; WRITE("</ifindex>\n");
}
#line 757 "inform7/Chapter 20/Release Instructions.w"
int write_var_to_XML(OUTPUT_STREAM, nonlocal_variable *nlv, int desc_mode) {
if ((nlv) && (Data__NonlocalVariables__has_initial_value_set(nlv))) {
Data__NonlocalVariables__treat_as_plain_text_word(nlv);
Data__NonlocalVariables__compile_initial_value(OUT, nlv);
return TRUE;
}
return FALSE;
}
#line 794 "inform7/Chapter 20/Release Instructions.w"
void write_release_blurb(OUTPUT_STREAM, char *materials_folder,
int cover_picture_number, char *cover_art_format) {
char story_file_leafname[128];
if (story_filename_extension == NULL) sprintf(story_file_leafname, "output.z5");
else sprintf(story_file_leafname, "output.%s", story_filename_extension);
TEMPORARY_STREAM;
{
#line 812 "inform7/Chapter 20/Release Instructions.w"
if ((story_title_VAR != NULL) &&
(Data__NonlocalVariables__has_initial_value_set(story_title_VAR))) {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(TRUNCATE_TEXT_CMODE);
Data__NonlocalVariables__compile_initial_value(TEMP, story_title_VAR);
END_COMPILATION_MODE;
} else STREAM_WRITE(TEMP, "story");
STREAM_WRITE(TEMP, ".%s", Code__VirtualMachines__get_blorbed_extension());
}
#line 802 "inform7/Chapter 20/Release Instructions.w"
;
WRITE("! Blurb file created by Inform build %s\n\n", NI_BUILD);
{
#line 824 "inform7/Chapter 20/Release Instructions.w"
{
#line 844 "inform7/Chapter 20/Release Instructions.w"
WRITE("status \"%s%cReserved%cCblorbModel.html\" \"%s%cBuild%cStatusCblorb.html\"\n\n",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR,
bundle_name, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
}
#line 824 "inform7/Chapter 20/Release Instructions.w"
;
WRITE("\n! Identification\n\n", NI_BUILD);
{
#line 851 "inform7/Chapter 20/Release Instructions.w"
WRITE("project folder \"%s\"\n", bundle_name);
if ((create_Materials) && (this_is_a_release_compile))
WRITE("release to \"%s%cRelease\"\n", materials_folder, FOLDER_SEPARATOR);
}
#line 826 "inform7/Chapter 20/Release Instructions.w"
;
WRITE("\n! Blorb instructions\n\n", NI_BUILD);
{
#line 858 "inform7/Chapter 20/Release Instructions.w"
WRITE("storyfile leafname \""); STREAM_COPY(OUT, TEMP); WRITE("\"\n");
if (existing_story_file) {
if (story_filename_extension == NULL)
WRITE("storyfile \"%s%cstory.z5\" include\n",
materials_folder, FOLDER_SEPARATOR);
else
WRITE("storyfile \"%s%cstory.%s\" include\n",
materials_folder, FOLDER_SEPARATOR, story_filename_extension);
} else {
WRITE("storyfile \"%s\" include\n",
Files__Filenames__build(story_file_leafname));
}
WRITE("ifiction \"%s\" include\n",
Files__Filenames__top_level(METADATA_LEAFNAME));
}
#line 828 "inform7/Chapter 20/Release Instructions.w"
;
{
#line 878 "inform7/Chapter 20/Release Instructions.w"
if (release_cover) {
WRITE("cover \"%s%cCover.%s\"\n",
materials_folder, FOLDER_SEPARATOR, cover_art_format);
WRITE("picture %d \"%s%cCover.%s\"\n", cover_picture_number,
materials_folder, FOLDER_SEPARATOR, cover_art_format);
} else {
WRITE("cover \"%s%cReserved%cDefaultCover.jpg\"\n",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
WRITE("picture %d \"%s%cReserved%cDefaultCover.jpg\"\n", 1,
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
if (release_website) {
WRITE("release file \"%s%cReserved%cCover.jpg\"\n",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
WRITE("release file \"%s%cReserved%cSmall Cover.jpg\"\n",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
}
}
}
#line 829 "inform7/Chapter 20/Release Instructions.w"
;
Plugins__Figures__write_blurb_commands(OUT, materials_folder);
Plugins__Sounds__write_blurb_commands(OUT, materials_folder);
WRITE("\n! Placeholder variables\n\n", NI_BUILD);
{
#line 902 "inform7/Chapter 20/Release Instructions.w"
WRITE("placeholder [IFID] = \"%s\"\n", Plugins__Bibliographic__read_uuid());
if (Data__NonlocalVariables__has_initial_value_set(story_release_number_VAR)) {
WRITE("placeholder [RELEASE] = \"");
Data__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 (Data__NonlocalVariables__has_initial_value_set(story_creation_year_VAR)) {
WRITE("placeholder [YEAR] = \"");
Data__NonlocalVariables__compile_initial_value(OUT, story_creation_year_VAR);
WRITE("\"\n");
} else WRITE("placeholder [YEAR] = \"%d\"\n", (the_present->tm_year)+1900);
if (Data__NonlocalVariables__has_initial_value_set(story_title_VAR)) {
Data__NonlocalVariables__treat_as_plain_text_word(story_title_VAR);
WRITE("placeholder [TITLE] = \"");
Data__NonlocalVariables__compile_initial_value(OUT, story_title_VAR);
WRITE("\"\n");
} else WRITE("placeholder [TITLE] = \"Untitled\"\n");
if (Data__NonlocalVariables__has_initial_value_set(story_author_VAR)) {
Data__NonlocalVariables__treat_as_plain_text_word(story_author_VAR);
WRITE("placeholder [AUTHOR] = \"");
Data__NonlocalVariables__compile_initial_value(OUT, story_author_VAR);
WRITE("\"\n");
} else WRITE("placeholder [AUTHOR] = \"Anonymous\"\n");
if (Data__NonlocalVariables__has_initial_value_set(story_description_VAR)) {
Data__NonlocalVariables__treat_as_plain_text_word(story_description_VAR);
WRITE("placeholder [BLURB] = \"");
Data__NonlocalVariables__compile_initial_value(OUT, story_description_VAR);
WRITE("\"\n");
} else WRITE("placeholder [BLURB] = \"A work of interactive fiction.\"\n");
END_COMPILATION_MODE;
}
#line 833 "inform7/Chapter 20/Release Instructions.w"
;
WRITE("\n! Other material to release\n\n", NI_BUILD);
{
#line 945 "inform7/Chapter 20/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 835 "inform7/Chapter 20/Release Instructions.w"
;
{
#line 961 "inform7/Chapter 20/Release Instructions.w"
auxiliary_file *af;
LOOP_OVER(af, auxiliary_file)
WRITE("auxiliary \"%s%c%s\" \"%s\" \"%s\"\n",
materials_folder, FOLDER_SEPARATOR,
af->leafname_in_materials_folder,
(af->brief_description)?(af->brief_description):"--",
(af->foldername_in_release_folder)?(af->foldername_in_release_folder):"--");
if (release_booklet)
WRITE("auxiliary \"%s%cReserved%cIntroductionToIF.pdf\" \"Introduction to IF\"\n",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
if (release_postcard) {
WRITE("auxiliary \"%s%cReserved%cPostcard.pdf\" \"IF Postcard\"\n",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
WRITE("placeholder [OTHERCREDITS] = \"The postcard was written by Andrew Plotkin "
"and designed by Lea Albaugh.\"\n");
}
}
#line 836 "inform7/Chapter 20/Release Instructions.w"
;
if (release_interpreter)
{
#line 982 "inform7/Chapter 20/Release Instructions.w"
WRITE("\n! Website instructions\n\n", NI_BUILD);
WRITE("placeholder [ENCODEDSTORYFILE] = \"");
STREAM_COPY(OUT, TEMP);
WRITE(".js\"\n");
WRITE("template path \"%s%cTemplates\"\n", materials_folder, FOLDER_SEPARATOR);
WRITE("template path \"%s\"\n", pathname_of_templates);
WRITE("template path \"%s%cReserved%cTemplates\"\n",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
if (interpreter_template_leafname == NULL)
interpreter_template_leafname = Code__VirtualMachines__get_default_interpreter();
char *ext = Code__VirtualMachines__get_blorbed_extension();
WRITE("placeholder [INTERPRETERSCRIPTS] = \" ");
auxiliary_file *af;
LOOP_OVER(af, auxiliary_file)
if (af->from_payload == JAVASCRIPT_PAYLOAD)
WRITE("<script src='%s'></script>", af->leafname_in_materials_folder);
LOOP_OVER(af, auxiliary_file)
if (af->from_payload == CSS_PAYLOAD)
WRITE("<link rel='stylesheet' href='%s' type='text/css' media='all'></link>",
af->leafname_in_materials_folder);
WRITE("\"\n");
WRITE("interpreter \"%s\" \"%c\"\n", interpreter_template_leafname, ext[0]);
WRITE("base64 \"%s\" to \"%s%cRelease%cinterpreter%c",
Files__Filenames__build(story_file_leafname),
materials_folder, FOLDER_SEPARATOR, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
STREAM_COPY(OUT, TEMP);
WRITE(".js\"\n");
}
#line 837 "inform7/Chapter 20/Release Instructions.w"
;
if (release_website)
{
#line 1013 "inform7/Chapter 20/Release Instructions.w"
WRITE("\n! Website instructions\n\n", NI_BUILD);
WRITE("template path \"%s%cTemplates\"\n", materials_folder, FOLDER_SEPARATOR);
WRITE("template path \"%s\"\n", pathname_of_templates);
WRITE("template path \"%s%cReserved%cTemplates\"\n",
pathname_of_built_in_extensions, FOLDER_SEPARATOR, FOLDER_SEPARATOR);
if (strcmp(website_template_leafname, "Classic") != 0) WRITE("css\n");
WRITE("website \"%s\"\n", website_template_leafname);
}
#line 838 "inform7/Chapter 20/Release Instructions.w"
;
{
#line 1027 "inform7/Chapter 20/Release Instructions.w"
parse_node *p;
TREE_LOOP(p)
if ((Parser__Nodes__type(p) == SENTENCE_NT)
&& (p->down)
&& (Parser__Nodes__int_annotation(p->down, verb_id_ANNOT) == RELEASE_VB)) {
int wn = p->word_ref1;
TEMPORARY_STREAM;
Index__link_to(TEMP, wn, TRUE);
WRITE("status instruction ||");
STREAM_COPY(OUT, TEMP);
WRITE("||\n");
CLOSE_TEMPORARY_STREAM;
}
if (release_cover == FALSE) {
WRITE("status alternative ||Using 'Release along with cover art', to "
"provide something more distinctive than the default artwork above");
Index__doc_link_to(OUT, "release_cover", FALSE);
WRITE("||\n");
}
if (release_website == FALSE) {
WRITE("status alternative ||Using 'Release along with a website'");
Index__doc_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__doc_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__doc_link_to(OUT, "release_files", FALSE);
WRITE("||\n");
}
if (release_source == FALSE) {
WRITE("status alternative ||Using 'Release along with the source text'");
Index__doc_link_to(OUT, "release_source", FALSE);
WRITE("||\n");
}
if (release_solution == FALSE) {
WRITE("status alternative ||Using 'Release along with a solution'");
Index__doc_link_to(OUT, "release_solution", FALSE);
WRITE("||\n");
}
if (release_card == FALSE) {
WRITE("status alternative ||Using 'Release along with the library card'");
Index__doc_link_to(OUT, "release_card", FALSE);
WRITE("||\n");
}
if (release_booklet == FALSE) {
WRITE("status alternative ||Using 'Release along with the introductory booklet'");
Index__doc_link_to(OUT, "release_booklet", FALSE);
WRITE("||\n");
}
if (release_postcard == FALSE) {
WRITE("status alternative ||Using 'Release along with the introductory postcard'");
Index__doc_link_to(OUT, "release_postcard", FALSE);
WRITE("||\n");
}
}
#line 839 "inform7/Chapter 20/Release Instructions.w"
;
}
#line 804 "inform7/Chapter 20/Release Instructions.w"
;
CLOSE_TEMPORARY_STREAM;
}
#line 60 "inform7/Chapter 20/List Constants.w"
int literal_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = kind_of_ll(empty_literal_list(w2, w1), FALSE);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = kind_of_ll(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 63 "inform7/Chapter 20/List Constants.w"
int literal_list_contents_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = add_to_ll(RP[1], RP[2], w1, w2, R[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = add_to_ll(RP[1], empty_literal_list(w1, w2), w1, w2, 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 20/List Constants.w"
int literal_list_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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__Unknown__new(w1, w2);
#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 20/List Constants.w"
#line 76 "inform7/Chapter 20/List Constants.w"
literal_list *empty_literal_list(int w1, int w2) {
literal_list *ll = find_list_at(w1);
if (ll == NULL) ll = CREATE(literal_list);
ll->word_ref1 = w1; ll->word_ref2 = w2; ll->entry_kind = K_value;
ll->listed_within_code = FALSE;
ll->kinds_known_to_be_inconsistent = FALSE;
ll->first_llist_entry = NULL;
ll->list_compiled = FALSE;
ll->list_text = NULL;
Kinds__RunTime__ensure_basic_heap_present();
return ll;
}
#line 97 "inform7/Chapter 20/List Constants.w"
literal_list *find_list_at(int incipit) {
literal_list *ll;
LOOP_OVER(ll, literal_list)
if (ll->word_ref1 == incipit)
return ll;
return NULL;
}
#line 110 "inform7/Chapter 20/List Constants.w"
literal_list *add_to_ll(specification *spec, literal_list *ll, int w1, int w2, 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 = find_list_at(w1);
if (ll2) ll = ll2;
ll->word_ref1 = w1; ll->word_ref2 = w2;
if (bad) ll->kinds_known_to_be_inconsistent = TRUE;
return ll;
}
#line 129 "inform7/Chapter 20/List Constants.w"
kind *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 = Parser__Sentences__NPs__new_raw(ll->word_ref1, ll->word_ref2);
current_sentence = ll->list_text;
}
kind *K = K_value;
llist_entry *lle;
for (lle = ll->first_llist_entry; lle; lle = lle->next_llist_entry) {
specification *spec = lle->llist_entry_value;
spec = Data__NonlocalVariables__substitute_constants(spec);
kind *E = NULL;
{
#line 155 "inform7/Chapter 20/List Constants.w"
if (Specifications__is_UNKNOWN(spec)) {
if (issue_problems)
{
#line 189 "inform7/Chapter 20/List Constants.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, spec->word_ref1, spec->word_ref2);
Problems__handmade_problem(_P_(C20BadConstantListEntry));
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 156 "inform7/Chapter 20/List Constants.w"
;
ll->kinds_known_to_be_inconsistent = TRUE;
E = K;
} else if ((Specifications__species_is(spec, CONSTANT_SPC) == FALSE) &&
(Specifications__Storage__is_constant_NONLOCAL_VARIABLE(spec) == FALSE)) {
if (issue_problems)
{
#line 203 "inform7/Chapter 20/List Constants.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, spec->word_ref1, spec->word_ref2);
Problems__quote_kind_of(3, spec);
Problems__handmade_problem(_P_(C20NonconstantConstantListEntry));
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 161 "inform7/Chapter 20/List Constants.w"
;
ll->kinds_known_to_be_inconsistent = TRUE;
E = K;
} else {
E = Specifications__evaluates_to(spec);
if (E == NULL) {
if (issue_problems)
{
#line 189 "inform7/Chapter 20/List Constants.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, spec->word_ref1, spec->word_ref2);
Problems__handmade_problem(_P_(C20BadConstantListEntry));
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 167 "inform7/Chapter 20/List Constants.w"
;
ll->kinds_known_to_be_inconsistent = TRUE;
}
}
}
#line 142 "inform7/Chapter 20/List Constants.w"
;
if (Kinds__eq(K, K_value)) K = E;
else
{
#line 178 "inform7/Chapter 20/List Constants.w"
kind *previous_K = K;
K = Kinds__max(E, K);
if (Kinds__eq(K, K_value)) {
if (issue_problems)
{
#line 216 "inform7/Chapter 20/List Constants.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, spec->word_ref1, spec->word_ref2);
Problems__quote_kind(3, E);
Problems__quote_kind(4, previous_K);
Problems__handmade_problem(_P_(C20IncompatibleConstantListEntry));
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 181 "inform7/Chapter 20/List Constants.w"
;
ll->kinds_known_to_be_inconsistent = TRUE;
break;
}
}
#line 144 "inform7/Chapter 20/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 232 "inform7/Chapter 20/List Constants.w"
kind *Data__Lists__kind_of_list_at(int incipit) {
literal_list *ll = find_list_at(incipit+1);
if (ll) return kind_of_ll(ll, FALSE);
return NULL;
}
void Data__Lists__check_one(int incipit) {
literal_list *ll = find_list_at(incipit+1);
if (ll) kind_of_ll(ll, TRUE);
}
#line 246 "inform7/Chapter 20/List Constants.w"
void Data__Lists__check(OUTPUT_STREAM) {
if (problem_count == 0) {
literal_list *ll;
LOOP_OVER(ll, literal_list)
kind_of_ll(ll, TRUE);
}
}
#line 259 "inform7/Chapter 20/List Constants.w"
void Data__Lists__compile_literal_list(OUTPUT_STREAM, int incipit) {
literal_list *ll = find_list_at(incipit+1);
if (ll) {
kind *K = kind_of_ll(ll, FALSE);
STREAM *BC = Kinds__RunTime__begin_block_constant(OUT, K);
STREAM_WRITE(BC, "LIST_CONST_%d 0", incipit+1);
Kinds__RunTime__end_block_constant(K);
}
}
#line 272 "inform7/Chapter 20/List Constants.w"
void Data__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;
kind_of_ll(ll, TRUE);
if (problem_count == 0)
{
#line 294 "inform7/Chapter 20/List Constants.w"
WRITE("Array LIST_CONST_%d --> ", ll->word_ref1);
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, kind_of_ll(ll, FALSE), TRUE, n+2);
Kinds__RuntimeIDs__compile_strong(OUT, ll->entry_kind);
WRITE(" %d ", n);
for (lle = ll->first_llist_entry; lle; lle = lle->next_llist_entry) {
specification *spec = lle->llist_entry_value;
WRITE("(");
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__compile_constant_to_kind(OUT, spec, ll->entry_kind);
END_COMPILATION_MODE;
WRITE(") ");
}
WRITE(";\n");
}
#line 281 "inform7/Chapter 20/List Constants.w"
;
}
}
#line 318 "inform7/Chapter 20/List Constants.w"
void Data__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__RuntimeIDs__compile_strong(OUT, Kinds__unary_construction_material(K));
WRITE(" 0;\n");
}
#line 64 "inform7/Chapter 20/Table Columns.w"
table_column *new_table_column(int w1, int w2) {
table_column *tc = CREATE(table_column);
tc->word_ref1 = w1; tc->word_ref2 = w2;
if (w1 >= 0) /* as always happens except when recovering from a problem */
Semantics__Nouns__ExcerptMeanings__register(TABLE_COLUMN_MC, 0, w1, w2,
STORE_POINTER_table_column(tc));
Semantics__Nouns__ExcerptMeanings__register_assemblage(TABLE_COLUMN_MC, 0,
Text__Languages__merge(table_column_name_construction_NTM, 0,
Text__Words__from_range(w1, w2)),
STORE_POINTER_table_column(tc));
tc->kind_stored_in_column = NULL;
tc->table_from_which_kind_inferred = NULL;
tc->listed_in_predicate = Data__Tables__Relations__make_listed_in_predicate(tc);
return tc;
}
#line 83 "inform7/Chapter 20/Table Columns.w"
void Data__Tables__Columns__log(table_column *tc) {
LOG("'$W'/", tc->word_ref1, tc->word_ref2);
if (tc->kind_stored_in_column == NULL) LOG("unknown");
else LOG("$u", tc->kind_stored_in_column);
}
#line 93 "inform7/Chapter 20/Table Columns.w"
specification *Data__Tables__Columns__to_specification(table_column *tc) {
kind *K = Kinds__unary_construction(CON_table_column, tc->kind_stored_in_column);
specification *spec = Specifications__Values__new_actual_CONSTANT(K);
Specifications__set_structure_field(spec, STORE_POINTER_table_column(tc));
return spec;
}
table_column *Data__Tables__Columns__from_specification(specification *spec) {
if (!(Specifications__Values__is_actual_CONSTANT_construction(spec, CON_table_column)))
internal_error("tried to find column inside SP of wrong type");
table_column *tc = RETRIEVE_POINTER_table_column(Specifications__get_structure_field(spec));
if (tc == NULL) internal_error("found NULL col within TABLE COLUMN spec");
return tc;
}
#line 120 "inform7/Chapter 20/Table Columns.w"
kind *Data__Tables__Columns__get_kind(table_column *tc) {
return tc->kind_stored_in_column;
}
void Data__Tables__Columns__set_kind(table_column *tc, table *t, kind *K) {
if (Kinds__get_construct(K) == CON_description)
{
#line 139 "inform7/Chapter 20/Table Columns.w"
Problems__quote_kind(4, K);
Problems__quote_kind(5, K);
Problems__quote_table(6, t);
Problems__table_problem(_P_(C20TableColumnDescription),
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 126 "inform7/Chapter 20/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__eq(K, K_understanding))
Data__Tables__Relations__supply_kind_for_listed_in_tc(tc->listed_in_predicate, K_snippet);
else Data__Tables__Relations__supply_kind_for_listed_in_tc(tc->listed_in_predicate, K);
}
#line 151 "inform7/Chapter 20/Table Columns.w"
binary_predicate *Data__Tables__Columns__get_listed_in_predicate(table_column *tc) {
return tc->listed_in_predicate;
}
#line 163 "inform7/Chapter 20/Table Columns.w"
int Data__Tables__Columns__get_id(table_column *tc) {
return 100 + tc->allocation_id;
}
void Data__Tables__Columns__compile_run_time_support(OUTPUT_STREAM) {
OUT = Code__Routines__begin(OUT, "TC_KOV");
Code__LocalVariables__add_named_call("tc");
WRITE("switch (tc) {\n"); INDENT;
table_column *tc;
LOOP_OVER(tc, table_column) {
WRITE("%d: return ", Data__Tables__Columns__get_id(tc));
Kinds__RuntimeIDs__compile_strong(OUT, Data__Tables__Columns__get_kind(tc));
WRITE("; ! ");
Text__print_text_to_stream(tc->word_ref1, tc->word_ref2, OUT);
WRITE(": ");
Kinds__Textual__write(OUT, Data__Tables__Columns__get_kind(tc));
WRITE("\n");
}
OUTDENT; WRITE("}\n");
WRITE("return UNKNOWN_TY;\n");
OUT = Code__Routines__end(OUT);
}
#line 192 "inform7/Chapter 20/Table Columns.w"
table_column_usage Data__Tables__Columns__add_to_table(int w1, int w2, table *t) {
int exp1 = -1, exp2 = -1;
table_column_usage tcu;
tcu.column_identity = find_table_column(w1, w2, t, &exp1, &exp2);
tcu.entries = Parser__Sentences__NPs__new_raw(w1, w2);
tcu.kind_declaration_w1 = exp1; tcu.kind_declaration_w2 = exp2;
tcu.actual_constant_entries = 0;
tcu.observed_constant_cell = NULL;
tcu.kind_name_entries = 0;
tcu.observed_kind_cell = NULL;
return tcu;
}
#line 223 "inform7/Chapter 20/Table Columns.w"
int table_column_heading_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 260 "inform7/Chapter 20/Table Columns.w"
*X = NEW_TC_PROBLEM;
Problems__table_problem(_P_(C20TableColumnBracketed),
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 224 "inform7/Chapter 20/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 = table_column_heading_NTM->range_result_w1[1]; k2_NTMV = table_column_heading_NTM->range_result_w2[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 = table_column_heading_NTM->range_result_w1[1]; k2_NTMV = table_column_heading_NTM->range_result_w2[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 229 "inform7/Chapter 20/Table Columns.w"
int table_column_heading_unbracketed_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 240 "inform7/Chapter 20/Table Columns.w"
*X = NEW_TC_PROBLEM;
Problems__quote_words(4, w1, w2);
Problems__table_problem(_P_(C20TableColumnArticle),
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 231 "inform7/Chapter 20/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 251 "inform7/Chapter 20/Table Columns.w"
*X = NEW_TC_PROBLEM;
Problems__table_problem(_P_(C20TableColumnAlready),
table_being_examined, NULL, table_cell_node,
"In %1, the column name %3 cannot be used, because it already means "
"something else.");
}
#line 234 "inform7/Chapter 20/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 236 "inform7/Chapter 20/Table Columns.w"
#line 272 "inform7/Chapter 20/Table Columns.w"
int table_column_name_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 274 "inform7/Chapter 20/Table Columns.w"
#line 280 "inform7/Chapter 20/Table Columns.w"
table_column *find_table_column(int w1, int w2, table *t, int *exp1, int *exp2) {
table_cell_node = Parser__Sentences__NPs__new_raw(w1, w2);
table_cell_row = -1;
table_cell_col = -1;
table_being_examined = t;
*exp1 = -1; *exp2 = -1;
parse_nt_against_word_range(table_column_heading_NTM, w1, w2, NULL, NULL);
table_column *tc = NULL;
kind *K = NULL;
switch (most_recent_result) {
case EXISTING_TC:
*exp1 = k1_NTMV; *exp2 = k2_NTMV;
tc = RETRIEVE_POINTER_table_column(
Semantics__Nouns__ExcerptMeanings__data(
Parser__SP__MeaningLists__meaning(most_recent_result_p)));
break;
case NEW_TC_TOPIC: K = K_understanding; break;
case NEW_TC_WITH_KIND: *exp1 = k1_NTMV; *exp2 = k2_NTMV; break;
case NEW_TC_WITHOUT_KIND: break;
case NEW_TC_PROBLEM: return NULL;
}
{
#line 313 "inform7/Chapter 20/Table Columns.w"
if ((K == NULL) && (*exp1 >= 0) && (parse_nt_against_word_range(k_kind_articled_NTM, *exp1, *exp2, NULL, NULL))) {
K = most_recent_result_p; *exp1 = -1; *exp2 = -1;
}
}
#line 301 "inform7/Chapter 20/Table Columns.w"
;
if (tc == NULL)
{
#line 320 "inform7/Chapter 20/Table Columns.w"
GET_RW(table_column_heading_unbracketed_NTM, 1, w1, w2);
if (Parser__Assertions__vet_name(w1, w2)) tc = new_table_column(w1, w2);
else return NULL;
}
#line 302 "inform7/Chapter 20/Table Columns.w"
;
if (K) Data__Tables__Columns__set_kind(tc, t, K);
return tc;
}
#line 329 "inform7/Chapter 20/Table Columns.w"
void Data__Tables__Columns__check_explicit_headings(table *t, int i, table_column_usage *tcu) {
kind *K = Data__Tables__Columns__get_kind(tcu->column_identity);
int w1 = tcu->kind_declaration_w1, w2 = tcu->kind_declaration_w2;
if (w1 >= 0) {
kind *EK = NULL;
if (parse_nt_against_word_range(k_kind_articled_NTM, w1, w2, NULL, NULL)) {
EK = most_recent_result_p;
LOGIF(TABLES, "$B col %d '$W' claims $u\n", t, i, w1, w2, EK);
if (K == NULL)
Data__Tables__Columns__set_kind(tcu->column_identity, t, EK);
else if (!(Kinds__eq(K, EK)))
{
#line 351 "inform7/Chapter 20/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__table_problem(_P_(C20TableColumnInconsistent),
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 340 "inform7/Chapter 20/Table Columns.w"
;
} else
{
#line 364 "inform7/Chapter 20/Table Columns.w"
Problems__table_problem(_P_(C20TableColumnBrackets),
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 341 "inform7/Chapter 20/Table Columns.w"
;
} else {
LOGIF(TABLES, "Column %d '$W' has no explicit kind named in $B\n",
i, w1, w2, t);
}
}
#line 376 "inform7/Chapter 20/Table Columns.w"
void Data__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 447 "inform7/Chapter 20/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__table_problem(_P_(C20TableKindTwice),
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 382 "inform7/Chapter 20/Table Columns.w"
else if (tcu->actual_constant_entries > 0)
{
#line 429 "inform7/Chapter 20/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__table_problem(_P_(C20TableKindBelowValue),
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 384 "inform7/Chapter 20/Table Columns.w"
else {
kind *CK = Data__Tables__Columns__get_kind(tcu->column_identity);
if (CK == NULL) {
Data__Tables__Columns__set_kind(tcu->column_identity, t, K);
return;
}
}
} else {
tcu->actual_constant_entries++;
if (tcu->observed_constant_cell == NULL) tcu->observed_constant_cell = cell;
if (tcu->kind_name_entries > 0)
{
#line 462 "inform7/Chapter 20/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__table_problem(_P_(C20TableValueBelowKind),
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 396 "inform7/Chapter 20/Table Columns.w"
;
}
kind *CK = Kinds__weaken(Data__Tables__Columns__get_kind(tcu->column_identity));
K = Kinds__weaken(K);
if (CK == NULL) {
Data__Tables__Columns__set_kind(tcu->column_identity, t, K);
} else {
int allow_refinement = TRUE;
if (Kinds__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__eq(K, CK) == FALSE) {
kind *max_K = Kinds__accumulative_max(K, CK);
if (Kinds__eq(max_K, K_value)) {
LOG("Incompatible types: K = $u, CK = $u\n", K, CK);
Problems__quote_kind(4, K);
Problems__quote_kind(5, CK);
if (t == tcu->column_identity->table_from_which_kind_inferred)
{
#line 481 "inform7/Chapter 20/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__table_problem(_P_(C20TableIncompatibleEntry),
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 415 "inform7/Chapter 20/Table Columns.w"
else
{
#line 492 "inform7/Chapter 20/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_words(7, tcu->column_identity->word_ref1, tcu->column_identity->word_ref2);
Problems__quote_number(8, &quoted_col);
Problems__quote_number(9, &table_cell_row);
Problems__table_problem(_P_(C20TableIncompatibleEntry2),
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 417 "inform7/Chapter 20/Table Columns.w"
;
allow_refinement = FALSE;
}
if (allow_refinement)
Data__Tables__Columns__set_kind(tcu->column_identity, t, max_K);
}
}
}
#line 509 "inform7/Chapter 20/Table Columns.w"
void Data__Tables__Columns__approve_kind(table *t, int i, table_column_usage *tcu) {
kind *K = Data__Tables__Columns__get_kind(tcu->column_identity);
LOGIF(TABLES, "Column %d '$W' has kind $u with data:\n$T",
i, tcu->column_identity->word_ref1, tcu->column_identity->word_ref2,
K, tcu->entries);
if ((Kinds__get_construct(K) == CON_list_of) &&
(Kinds__eq(Kinds__unary_construction_material(K), K_value))) {
Problems__table_problem(_P_(C20TableColumnEmptyLists),
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__table_problem(_P_(C20TableKindlessColumn),
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.");
Data__Tables__Columns__set_kind(tcu->column_identity, t, K_number);
}
}
#line 76 "inform7/Chapter 20/Tables.w"
sentence_handler TABLE_SH_handler = { TABLE_NT, -1, 0, NULL };
#line 83 "inform7/Chapter 20/Tables.w"
void Data__Tables__traverse_to_create(void) {
parse_node *p;
TREE_LOOP(p)
if (Parser__Nodes__type(p) == TABLE_NT)
create_table(p);
}
#line 97 "inform7/Chapter 20/Tables.w"
void Data__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;
stock_table(t, phase);
}
}
}
#line 113 "inform7/Chapter 20/Tables.w"
void Data__Tables__check_tables_for_kind_clashes(void) {
table *t;
LOOP_OVER(t, table) {
int t1 = t->table_name_w1, t2 = t->table_name_w2;
if ((t1 >= 0) && (parse_nt_against_word_range(k_kind_articled_NTM, t1, t2, NULL, NULL)) &&
(Kinds__lt(most_recent_result_p, K_object))) {
Problems__quote_table(1, t);
Problems__quote_words(2, t->table_name_w1, t->table_name_w2);
Problems__handmade_problem(_P_(C20TableCoincidesWithKind));
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 136 "inform7/Chapter 20/Tables.w"
table *new_table_structure(void) {
table *t = CREATE(table);
t->table_no_w1 = -1; t->table_no_w2 = -1;
t->table_name_w1 = -1; t->table_name_w2 = -1;
t->headline_fragment = NULL;
t->blank_rows = 0;
t->blank_rows_for_each_w1 = -1; t->blank_rows_for_each_w2 = -1;
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;
sprintf(t->tab_I6_identifier, "T%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;
add_table_contribution(t, current_sentence);
return t;
}
#line 162 "inform7/Chapter 20/Tables.w"
void 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 174 "inform7/Chapter 20/Tables.w"
void Data__Tables__log(table *t) {
LOG("{%s}", t->tab_I6_identifier);
}
#line 181 "inform7/Chapter 20/Tables.w"
int Data__Tables__get_no_columns(table *t) {
return t->no_columns;
}
int Data__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 195 "inform7/Chapter 20/Tables.w"
int Data__Tables__expand_block_constants(table *t) {
if (t->amendment_of) return FALSE;
if (t->disable_block_constant_correction) return FALSE;
return TRUE;
}
kind *Data__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 Data__Tables__Columns__get_kind(t->columns[i].column_identity);
}
#line 210 "inform7/Chapter 20/Tables.w"
char *Data__Tables__identifier(table *t) {
return t->tab_I6_identifier;
}
parse_node *Data__Tables__get_headline(table *t) {
return t->headline_fragment;
}
#line 249 "inform7/Chapter 20/Tables.w"
int table_header_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 254 "inform7/Chapter 20/Tables.w"
int table_new_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 264 "inform7/Chapter 20/Tables.w"
*X = TABLE_HAS_ONLY_NAME; /* for recovery */
Problems__sentence_problem(_P_(C20TableMisnamed),
"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 259 "inform7/Chapter 20/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 260 "inform7/Chapter 20/Tables.w"
#line 277 "inform7/Chapter 20/Tables.w"
int table_names_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 280 "inform7/Chapter 20/Tables.w"
#line 287 "inform7/Chapter 20/Tables.w"
int table_footer_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 290 "inform7/Chapter 20/Tables.w"
#line 301 "inform7/Chapter 20/Tables.w"
void create_table(parse_node *PN) {
int w1 = PN->word_ref1, w2 = PN->word_ref2;
int connection = TABLE_IS_NEW; /* i.e., no connection with existing tables */
table *t = new_table_structure();
int headline_w1 = w1, headline_w2 = Text__last_word_of_formatted_text(w1, w2, FALSE);
if (headline_w1 == headline_w2)
{
#line 337 "inform7/Chapter 20/Tables.w"
Problems__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 307 "inform7/Chapter 20/Tables.w"
;
t->headline_fragment = Parser__Sentences__NPs__new_raw(headline_w1, headline_w2);
current_sentence = t->headline_fragment;
{
#line 346 "inform7/Chapter 20/Tables.w"
LOGIF(TABLES, "Parsing table headline $W\n", headline_w1, headline_w2);
parse_nt_against_word_range(table_header_NTM, headline_w1, headline_w2, NULL, NULL);
connection = most_recent_result;
switch (nameforms_NTMV) {
case TABLE_HAS_ONLY_NUMBER:
GET_RW(table_new_name_NTM, 1, (t->table_no_w1), (t->table_no_w2));
break;
case TABLE_HAS_ONLY_NAME:
GET_RW(table_new_name_NTM, 1, (t->table_name_w1), (t->table_name_w2));
break;
case TABLE_HAS_NUMBER_AND_NAME:
GET_RW(table_new_name_NTM, 1, (t->table_no_w1), (t->table_no_w2));
GET_RW(table_new_name_NTM, 2, (t->table_name_w1), (t->table_name_w2));
break;
}
}
#line 311 "inform7/Chapter 20/Tables.w"
;
{
#line 366 "inform7/Chapter 20/Tables.w"
if (parse_nt_against_word_range(spec_type_expression_or_value_NTM, t->table_name_w1, t->table_name_w2, NULL, NULL)) {
Problems__quote_words_as_source(1, t->table_name_w1, t->table_name_w2);
Problems__handmade_problem(_P_(C20TableNameAmbiguous));
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 312 "inform7/Chapter 20/Tables.w"
;
table *existing_table_with_same_name = NULL;
{
#line 399 "inform7/Chapter 20/Tables.w"
if ((t->table_name_w1 >= 0) && (t->table_no_w1 >= 0)) {
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 (t->table_name_w1 >= 0) {
table *t2;
LOOP_OVER(t2, table)
if (TABLE_NAMES_MATCH(t2, t)) {
if ((t->table_no_w1 >= 0) && (!(TABLE_NUMBERS_MATCH(t2, t))))
continue;
existing_table_with_same_name = t2;
}
} else if (t->table_no_w1 >= 0) {
table *t2;
LOOP_OVER(t2, table)
if (TABLE_NUMBERS_MATCH(t2, t))
existing_table_with_same_name = t2;
}
}
#line 315 "inform7/Chapter 20/Tables.w"
;
if (connection != TABLE_IS_NEW)
{
#line 422 "inform7/Chapter 20/Tables.w"
if (existing_table_with_same_name == NULL) {
Problems__quote_table(1, t);
Problems__handmade_problem(_P_(C20TableNotContinuation));
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 316 "inform7/Chapter 20/Tables.w"
else
{
#line 438 "inform7/Chapter 20/Tables.w"
if (existing_table_with_same_name) {
Problems__quote_table(1, t);
Problems__quote_table(2, existing_table_with_same_name);
Problems__quote_words(3, headline_w1, headline_w2);
Problems__handmade_problem(_P_(C20TableNameDuplicate));
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 317 "inform7/Chapter 20/Tables.w"
;
Formats__Inform6__compose_identifier(t->tab_I6_identifier, 'T', t->allocation_id,
t->table_name_w1, t->table_name_w2);
if (connection == TABLE_IS_NEW) {
{
#line 456 "inform7/Chapter 20/Tables.w"
if (t->table_no_w1 >= 0) {
LOGIF(TABLES, "Registering table by number: table $W\n",
t->table_no_w1, t->table_no_w2);
Semantics__Nouns__ExcerptMeanings__register_assemblage(TABLE_MC, 0,
Text__Languages__merge(table_names_construction_NTM, 0,
Text__Words__from_range(t->table_no_w1, t->table_no_w2)),
STORE_POINTER_table(t));
}
if (t->table_name_w1 >= 0) {
LOGIF(TABLES, "Registering table by name: table of $W\n",
t->table_name_w1, t->table_name_w2);
Semantics__Nouns__ExcerptMeanings__register_assemblage(TABLE_MC, 0,
Text__Languages__merge(table_names_construction_NTM, 1,
Text__Words__from_range(t->table_name_w1, t->table_name_w2)),
STORE_POINTER_table(t));
}
}
#line 322 "inform7/Chapter 20/Tables.w"
;
LOGIF(TABLES, "Created: $B\n", t);
}
{
#line 476 "inform7/Chapter 20/Tables.w"
if (parse_nt_against_word_range(table_footer_NTM, w1, w2, NULL, NULL)) {
GET_RW(table_footer_NTM, 1, w1, w2);
if (each_NTMV) {
int x1, x2;
GET_RW(table_footer_NTM, 2, x1, x2);
t->blank_rows_for_each_w1 = x1; t->blank_rows_for_each_w2 = x2;
} else t->blank_rows = most_recent_result;
}
}
#line 326 "inform7/Chapter 20/Tables.w"
;
int row_count = 0;
{
#line 492 "inform7/Chapter 20/Tables.w"
int pos = headline_w2+1;
while (pos <= w2) {
int col_count = 0;
int row_end = Text__last_word_of_formatted_text(pos, w2, FALSE);
LOGIF(TABLES, "Row %d is $W\n", row_count, pos, row_end);
while (pos <= row_end) {
int cell_end = Text__last_word_of_formatted_text(pos, row_end, TRUE);
LOGIF(TABLES, "Cell (%d, %d) is $W\n", row_count, col_count, pos, cell_end);
if (row_count == 0)
{
#line 518 "inform7/Chapter 20/Tables.w"
current_sentence = PN;
if (col_count == MAX_COLUMNS_PER_TABLE) {
parse_node *overflow = Parser__Sentences__NPs__new_raw(pos, cell_end);
int limit = MAX_COLUMNS_PER_TABLE;
Problems__quote_number(4, &limit);
Problems__table_problem(_P_(C20TableTooManyColumns),
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, pos, cell_end);
t->columns[t->no_columns] = Data__Tables__Columns__add_to_table(pos, cell_end, t);
if (t->columns[t->no_columns].column_identity) /* i.e., no Problem occurred */
t->no_columns++;
}
}
#line 500 "inform7/Chapter 20/Tables.w"
else
{
#line 538 "inform7/Chapter 20/Tables.w"
parse_node *cell = Parser__Sentences__NPs__new_raw(pos, cell_end);
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__table_problem(_P_(C20TableRowFull),
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 {
Parser__Nodes__annotate_int(cell, table_cell_unspecified_ANNOT, FALSE);
Parser__Nodes__graft(cell, t->columns[col_count].entries);
}
}
#line 501 "inform7/Chapter 20/Tables.w"
;
col_count++;
pos = cell_end + 1;
}
{
#line 558 "inform7/Chapter 20/Tables.w"
while (col_count < t->no_columns) { /* which can only happen on data rows */
parse_node *cell = Parser__Sentences__NPs__new_raw(-1, -1);
Parser__Nodes__annotate_int(cell, table_cell_unspecified_ANNOT, TRUE);
Parser__Nodes__graft(cell, t->columns[col_count].entries);
col_count++;
}
}
#line 505 "inform7/Chapter 20/Tables.w"
;
row_count++;
}
if ((row_count < 2) && (t->blank_rows == 0)) {
Problems__table_problem(_P_(C20TableWithoutRows),
t, NULL, PN, "%1 has no rows.");
return;
}
}
#line 328 "inform7/Chapter 20/Tables.w"
;
if (connection != TABLE_IS_NEW)
{
#line 568 "inform7/Chapter 20/Tables.w"
table *old_t = existing_table_with_same_name;
add_table_contribution(old_t, t->headline_fragment);
int new_to_old[MAX_COLUMNS_PER_TABLE], old_to_new[MAX_COLUMNS_PER_TABLE];
{
#line 590 "inform7/Chapter 20/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->word_ref1,
old_t->columns[j].column_identity->word_ref2);
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->word_ref1,
t->columns[i].column_identity->word_ref2);
LOGIF(TABLES, "\n");
}
#line 571 "inform7/Chapter 20/Tables.w"
;
switch (connection) {
case TABLE_IS_CONTINUED:
{
#line 614 "inform7/Chapter 20/Tables.w"
{
#line 696 "inform7/Chapter 20/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__handmade_problem(_P_(C20TableContinuationAddsCols));
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 771 "inform7/Chapter 20/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) STREAM_WRITE(TEMP, ", ");
Text__print_raw_text_to_stream(
old_t->columns[j].column_identity->word_ref1,
old_t->columns[j].column_identity->word_ref2,
TEMP);
}
STREAM_WRITE(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) STREAM_WRITE(TEMP, ", ");
Text__print_raw_text_to_stream(
t->columns[i].column_identity->word_ref1,
t->columns[i].column_identity->word_ref2,
TEMP);
}
STREAM_WRITE(TEMP, ".");
Problems__issue_problem_segment(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
Problems__issue_problem_end();
}
#line 713 "inform7/Chapter 20/Tables.w"
;
DESTROY(t, table);
return;
}
}
#line 614 "inform7/Chapter 20/Tables.w"
;
{
#line 637 "inform7/Chapter 20/Tables.w"
old_t->blank_rows += t->blank_rows;
if (t->blank_rows_for_each_w1 >= 0) {
if (old_t->blank_rows_for_each_w1 >= 0) {
current_sentence = t->table_created_at->source_table;
Problems__quote_table(1, t);
Problems__quote_table(2, old_t);
Problems__quote_words(3,
old_t->blank_rows_for_each_w1, old_t->blank_rows_for_each_w2);
Problems__quote_words(4,
t->blank_rows_for_each_w1, t->blank_rows_for_each_w2);
Problems__handmade_problem(_P_(C20TableContinuationContradicts));
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_w1 = t->blank_rows_for_each_w1;
old_t->blank_rows_for_each_w2 = t->blank_rows_for_each_w2;
}
}
#line 615 "inform7/Chapter 20/Tables.w"
;
if (row_count >= 2) {
int j;
for (j=0; j<old_t->no_columns; j++)
if (old_to_new[j] >= 0) {
Parser__Nodes__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 = Parser__Sentences__NPs__new_raw(-1, -1);
Parser__Nodes__annotate_int(blank, table_cell_unspecified_ANNOT, TRUE);
Parser__Nodes__graft(blank, old_t->columns[j].entries);
}
}
}
DESTROY(t, table);
}
#line 573 "inform7/Chapter 20/Tables.w"
; break;
case TABLE_IS_AMENDED:
{
#line 687 "inform7/Chapter 20/Tables.w"
{
#line 747 "inform7/Chapter 20/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__handmade_problem(_P_(C20TableAmendmentMisfit));
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 771 "inform7/Chapter 20/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) STREAM_WRITE(TEMP, ", ");
Text__print_raw_text_to_stream(
old_t->columns[j].column_identity->word_ref1,
old_t->columns[j].column_identity->word_ref2,
TEMP);
}
STREAM_WRITE(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) STREAM_WRITE(TEMP, ", ");
Text__print_raw_text_to_stream(
t->columns[i].column_identity->word_ref1,
t->columns[i].column_identity->word_ref2,
TEMP);
}
STREAM_WRITE(TEMP, ".");
Problems__issue_problem_segment(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
Problems__issue_problem_end();
}
#line 763 "inform7/Chapter 20/Tables.w"
;
DESTROY(t, table);
return;
}
}
#line 687 "inform7/Chapter 20/Tables.w"
;
t->amendment_of = old_t;
LOGIF(TABLES, "Amendment table created pro tem\n");
}
#line 574 "inform7/Chapter 20/Tables.w"
; break;
case TABLE_IS_REPLACED:
{
#line 661 "inform7/Chapter 20/Tables.w"
{
#line 723 "inform7/Chapter 20/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__handmade_problem(_P_(C20TableReplacementMissesCols));
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 771 "inform7/Chapter 20/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) STREAM_WRITE(TEMP, ", ");
Text__print_raw_text_to_stream(
old_t->columns[j].column_identity->word_ref1,
old_t->columns[j].column_identity->word_ref2,
TEMP);
}
STREAM_WRITE(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) STREAM_WRITE(TEMP, ", ");
Text__print_raw_text_to_stream(
t->columns[i].column_identity->word_ref1,
t->columns[i].column_identity->word_ref2,
TEMP);
}
STREAM_WRITE(TEMP, ".");
Problems__issue_problem_segment(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
Problems__issue_problem_end();
}
#line 738 "inform7/Chapter 20/Tables.w"
;
DESTROY(t, table);
return;
}
}
#line 661 "inform7/Chapter 20/Tables.w"
;
{
#line 677 "inform7/Chapter 20/Tables.w"
old_t->blank_rows = t->blank_rows;
old_t->blank_rows_for_each_w1 = t->blank_rows_for_each_w1;
old_t->blank_rows_for_each_w2 = t->blank_rows_for_each_w2;
}
#line 662 "inform7/Chapter 20/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 575 "inform7/Chapter 20/Tables.w"
; break;
default: internal_error("unknown form of table connection");
}
}
#line 331 "inform7/Chapter 20/Tables.w"
;
}
#line 812 "inform7/Chapter 20/Tables.w"
void 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++) {
switch (phase) {
case 1: Data__Tables__Columns__check_explicit_headings(t, i, &(t->columns[i]));
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 (PN->word_ref1 >= 0) /* if there's anything written there at all */
stock_table_cell(t, PN, row_count, i);
Parser__SP__MeaningLists__finish_this_session();
break;
}
case 3: Data__Tables__Columns__approve_kind(t, i, &(t->columns[i]));
break;
}
}
}
#line 862 "inform7/Chapter 20/Tables.w"
int table_cell_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 887 "inform7/Chapter 20/Tables.w"
*X = BLANK_TABLE_ENTRY;
*XP = Specifications__Unknown__new(w1, w2);
}
#line 863 "inform7/Chapter 20/Tables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 893 "inform7/Chapter 20/Tables.w"
*X = KIND_TABLE_ENTRY;
specification *new = Specifications__Values__new_generic_CONSTANT(RP[1]);
new->word_ref1 = w1; new->word_ref2 = w2;
*XP = new;
}
#line 864 "inform7/Chapter 20/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 911 "inform7/Chapter 20/Tables.w"
*X = PROBLEMATIC_TABLE_ENTRY;
nonlocal_variable *q = RETRIEVE_POINTER_nonlocal_variable(
Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(RP[1])));
if (q == NULL) internal_error("no such variable");
inference_subject *infs = Data__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_words(5,
table_being_examined->columns[table_cell_col].column_identity->word_ref1,
table_being_examined->columns[table_cell_col].column_identity->word_ref2);
Problems__quote_number(6, &table_cell_row);
Problems__quote_subject(7, infs);
Problems__table_problem(_P_(C20TablePlayerEntry),
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_words(5,
table_being_examined->columns[table_cell_col].column_identity->word_ref1,
table_being_examined->columns[table_cell_col].column_identity->word_ref2);
Problems__quote_number(6, &table_cell_row);
Problems__table_problem(_P_(C20TableVariableEntry),
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 866 "inform7/Chapter 20/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 901 "inform7/Chapter 20/Tables.w"
*X = TOPIC_TABLE_ENTRY;
specification *new = Specifications__Values__new_generic_CONSTANT(K_text);
new->word_ref1 = w1; new->word_ref2 = w2;
*XP = new;
}
#line 868 "inform7/Chapter 20/Tables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 946 "inform7/Chapter 20/Tables.w"
*X = PROBLEMATIC_TABLE_ENTRY;
{
#line 952 "inform7/Chapter 20/Tables.w"
int quoted_col = table_cell_col + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_words(5,
table_being_examined->columns[table_cell_col].column_identity->word_ref1,
table_being_examined->columns[table_cell_col].column_identity->word_ref2);
Problems__quote_number(6, &table_cell_row);
Problems__table_problem(_P_(C20TableUnknownEntry),
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 947 "inform7/Chapter 20/Tables.w"
;
}
#line 869 "inform7/Chapter 20/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 870 "inform7/Chapter 20/Tables.w"
int table_cell_blank_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 873 "inform7/Chapter 20/Tables.w"
int table_cell_value_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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: *X = INSTANCE_TABLE_ENTRY; *XP = Data__Instances__get_value(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *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 879 "inform7/Chapter 20/Tables.w"
int list_of_double_quotes_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 883 "inform7/Chapter 20/Tables.w"
#line 970 "inform7/Chapter 20/Tables.w"
void 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 990 "inform7/Chapter 20/Tables.w"
parse_nt_against_word_range(table_cell_NTM, cell->word_ref1, cell->word_ref2, NULL, NULL);
specification *spec = most_recent_result_p;
switch (most_recent_result) {
case BLANK_TABLE_ENTRY:
Parser__Nodes__annotate_int(cell, table_cell_unspecified_ANNOT, TRUE);
return;
case SPEC_TABLE_ENTRY:
Parser__Nodes__noun_from_value(cell, spec);
break;
case NAMED_CONSTANT_ENTRY:
topic_exception = TRUE;
Parser__Nodes__noun_from_value(cell, spec);
break;
case INSTANCE_TABLE_ENTRY:
Parser__Nodes__noun_from_value(cell, spec);
break;
case KIND_TABLE_ENTRY:
Parser__Nodes__annotate_int(cell, table_cell_unspecified_ANNOT, TRUE);
kind *K = Specifications__get_kind(spec);
Data__Tables__Columns__note_kind(t, col_count, &(t->columns[col_count]), cell,
K, TRUE);
return;
case ACTION_TABLE_ENTRY:
Parser__Nodes__annotate_int(cell, table_cell_allocated_ANNOT, TRUE);
Parser__Nodes__noun_from_value(cell, spec);
break;
case TOPIC_TABLE_ENTRY:
Parser__Nodes__noun_from_value(cell, spec);
topic_exception = TRUE;
break;
case PROBLEMATIC_TABLE_ENTRY:
return;
}
}
#line 977 "inform7/Chapter 20/Tables.w"
;
specification *evaluation = Parser__Nodes__get_evaluation(cell);
LOGIF(TABLES, "Cell evaluates to: $S\n", evaluation);
if (topic_exception == FALSE)
{
#line 1027 "inform7/Chapter 20/Tables.w"
if ((Specifications__Values__is_generic_CONSTANT(evaluation)) ||
(Specifications__species_is(evaluation, DESCRIPTION_SPC))) {
LOG("Evaluation is $S\n", evaluation);
int quoted_col = table_cell_col + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_words(5,
table_being_examined->columns[table_cell_col].column_identity->word_ref1,
table_being_examined->columns[table_cell_col].column_identity->word_ref2);
Problems__quote_number(6, &table_cell_row);
Problems__table_problem(_P_(C20TableDescriptionEntry),
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 (Specifications__Values__is_actual_CONSTANT(evaluation) == FALSE) {
LOG("Evaluation is $S\n", evaluation);
{
#line 952 "inform7/Chapter 20/Tables.w"
int quoted_col = table_cell_col + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_words(5,
table_being_examined->columns[table_cell_col].column_identity->word_ref1,
table_being_examined->columns[table_cell_col].column_identity->word_ref2);
Problems__quote_number(6, &table_cell_row);
Problems__table_problem(_P_(C20TableUnknownEntry),
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 1044 "inform7/Chapter 20/Tables.w"
;
}
}
#line 981 "inform7/Chapter 20/Tables.w"
;
Data__Tables__Columns__note_kind(t, col_count, &(t->columns[col_count]), cell,
Specifications__evaluates_to(evaluation), FALSE);
}
#line 1051 "inform7/Chapter 20/Tables.w"
void Data__Tables__complete(void) {
{
#line 1059 "inform7/Chapter 20/Tables.w"
table *t;
LOOP_OVER(t, table)
if (t->amendment_of)
amend_table(t->amendment_of, t);
}
#line 1052 "inform7/Chapter 20/Tables.w"
;
{
#line 1067 "inform7/Chapter 20/Tables.w"
table *t;
LOOP_OVER(t, table)
if (t->amendment_of == FALSE) {
current_sentence = t->table_created_at->source_table;
int b1 = t->blank_rows_for_each_w1, b2 = t->blank_rows_for_each_w2;
if (b1 >= 0) {
kind *K = NULL;
if (parse_nt_against_word_range(k_kind_NTM, b1, b2, NULL, NULL)) {
K = most_recent_result_p;
t->blank_rows += Data__Instances__count(K);
} else {
Problems__quote_words(4, b1, b2);
Problems__table_problem(_P_(C20TableKindlessBlanks),
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 1053 "inform7/Chapter 20/Tables.w"
;
}
#line 1101 "inform7/Chapter 20/Tables.w"
void 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 1133 "inform7/Chapter 20/Tables.w"
int col, matches_in_last_round = 0;
{
#line 1154 "inform7/Chapter 20/Tables.w"
parse_node *leftmost_cell;
for (leftmost_cell = main_table->columns[0].entries->down;
leftmost_cell;
leftmost_cell = leftmost_cell->next) {
Parser__Nodes__annotate_int(leftmost_cell, row_amendable_ANNOT, TRUE);
matches_in_last_round++;
}
}
#line 1134 "inform7/Chapter 20/Tables.w"
;
for (col = 0; col < main_table->no_columns; col++) {
parse_node *amend_cell;
{
#line 1165 "inform7/Chapter 20/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 1137 "inform7/Chapter 20/Tables.w"
;
if (Parser__Nodes__int_annotation(amend_cell, table_cell_unspecified_ANNOT) == FALSE) {
int only_row_left = -1;
{
#line 1180 "inform7/Chapter 20/Tables.w"
specification *amend_key = Parser__Nodes__get_evaluation(amend_cell);
LOGIF(TABLES, "Amend row %d, col %d, key $S: $T\n", amend_row, col, amend_key, amend_cell);
if (Specifications__Values__is_actual_CONSTANT(amend_key) == FALSE)
internal_error("bad key in amendments table"); /* code above should make this impossible */
int matches = 0;
{
#line 1199 "inform7/Chapter 20/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) {
specification *main_value = Parser__Nodes__get_evaluation(main_cell);
if (Parser__Nodes__int_annotation(leftmost_cell, row_amendable_ANNOT))
{
#line 1218 "inform7/Chapter 20/Tables.w"
LOG("Key in row %d is $S\n", row, main_value);
if ((Specifications__Values__is_actual_CONSTANT(main_value)) &&
(Specifications__Values__compare_CONSTANT(amend_key, main_value))) {
matches++;
only_row_left = row;
} else {
Parser__Nodes__annotate_int(leftmost_cell, row_amendable_ANNOT, FALSE);
}
}
#line 1211 "inform7/Chapter 20/Tables.w"
;
}
}
#line 1186 "inform7/Chapter 20/Tables.w"
;
if (matches == 0)
{
#line 1231 "inform7/Chapter 20/Tables.w"
{
#line 1258 "inform7/Chapter 20/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__handmade_problem(_P_(C20TableAmendmentMismatch));
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 1231 "inform7/Chapter 20/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_words(4, main_table->columns[col].column_identity->word_ref1,
main_table->columns[col].column_identity->word_ref2);
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 1187 "inform7/Chapter 20/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 1140 "inform7/Chapter 20/Tables.w"
;
if (only_row_left >= 0) {
splice_table_row(main_table, amendments, only_row_left, amend_row);
break;
}
}
}
}
#line 1108 "inform7/Chapter 20/Tables.w"
;
}
#line 1278 "inform7/Chapter 20/Tables.w"
void 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)) {
Parser__Nodes__copy_noun_details(cell_to, cell_from);
Parser__Nodes__annotate_int(cell_to, table_cell_unspecified_ANNOT,
Parser__Nodes__int_annotation(cell_from, table_cell_unspecified_ANNOT));
} else internal_error("bad table row splice");
}
}
#line 1302 "inform7/Chapter 20/Tables.w"
void Data__Tables__index(void) {
INDEX("<p>");
int m = 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) index_tables_in(ef, efc++);
Index__extra_div_close("e0e0e0");
INDEX("</p>");
}
#line 1319 "inform7/Chapter 20/Tables.w"
int index_tables_in(extension_file *ef, int efc) {
int tc = 0; table *t;
LOOP_OVER(t, table) if (table_within(t, ef)) tc++;
if (tc > 0) {
if (ef) {
if (efc > 0) INDEX("<br>");
INDEX("<i>");
Text__print_raw_text_to_stream(ef->name_w1, ef->name_w2, ifl);
INDEX("</i></p><p>");
}
Formats__HTML__begin_plain_html_table(ifl);
LOOP_OVER(t, table)
if (table_within(t, ef))
{
#line 1342 "inform7/Chapter 20/Tables.w"
Formats__HTML__first_html_column_spaced(ifl, 0);
INDEX("<b>");
Text__print_raw_text_to_stream(
t->headline_fragment->word_ref1,
t->headline_fragment->word_ref2, ifl);
INDEX("</b>");
table_contribution *tc; int ntc = 0;
for (tc = t->table_created_at; tc; tc = tc->next) {
if (ntc++ > 0) INDEX(" +");
Index__link(tc->source_table->word_ref1);
}
Formats__HTML__next_html_column_spaced(ifl, 0);
int rc = Data__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 (t->blank_rows_for_each_w1 >= 0) {
INDEX(", one for each ");
Text__print_raw_text_to_stream(
t->blank_rows_for_each_w1, t->blank_rows_for_each_w2, ifl);
}
INDEX(")");
}
INDEX("</small></i>");
Formats__HTML__end_html_row(ifl);
int col;
for (col = 0; col < t->no_columns; col++) {
Formats__HTML__first_html_column(ifl, 0);
INDEX("&nbsp;&nbsp;col %d:&nbsp;&nbsp;", col+1);
int cw1 = t->columns[col].column_identity->word_ref1,
cw2 = t->columns[col].column_identity->word_ref2;
if ((t->first_column_by_definition) && (col == 0)) {
parse_node *PN = t->where_used_to_define;
Text__print_raw_text_to_stream(PN->word_ref1, PN->word_ref2, ifl);
Index__link(PN->word_ref1);
} else {
if (t->first_column_by_definition) INDEX("<i>sets</i> ");
Text__print_raw_text_to_stream(cw1, cw2, ifl);
INDEX("&nbsp;");
TEMPORARY_STREAM;
Text__print_raw_text_to_stream(cw1, cw2, TEMP);
if (t->first_column_by_definition == FALSE) STREAM_WRITE(TEMP, " entry");
Formats__HTML__Javascript__paste(ifl, -1, -1, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
Formats__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(", ");
Text__print_raw_text_to_stream(cell->word_ref1, cell->word_ref2, ifl);
Index__link(cell->word_ref1);
}
} else if (t->first_column_by_definition) {
Kinds__Textual__write(ifl,
Data__Tables__Columns__get_kind(
t->columns[col].column_identity));
INDEX(" property");
} else {
INDEX("of ");
Kinds__Textual__write_plural(ifl,
Data__Tables__Columns__get_kind(
t->columns[col].column_identity));
}
Formats__HTML__end_html_row(ifl);
}
}
#line 1332 "inform7/Chapter 20/Tables.w"
;
Formats__HTML__end_html_table(ifl);
}
return tc;
}
#line 1422 "inform7/Chapter 20/Tables.w"
int table_within(table *t, extension_file *ef) {
if (t->amendment_of) return FALSE;
int at = t->table_created_at->source_table->word_ref1;
heading *at_heading =
Parser__Sentences__Headings__heading_of(Text__word_location(at));
extension_file *at_ef =
Parser__Sentences__Headings__get_extension_containing(at_heading);
if (ef == at_ef) return TRUE;
return FALSE;
}
#line 16 "inform7/Chapter 20/Runtime Support for Tables.w"
void Data__Tables__compile(OUTPUT_STREAM) {
{
#line 27 "inform7/Chapter 20/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 20/Runtime Support for Tables.w"
int words_used = 0;
current_sentence = t->table_created_at->source_table;
{
#line 63 "inform7/Chapter 20/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 20/Runtime Support for Tables.w"
;
int j;
for (j=0; j<t->no_columns; j++)
{
#line 87 "inform7/Chapter 20/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 = Data__Tables__Columns__get_kind(tc);
int bits = 0; /* bitmap of some properties of the column */
{
#line 150 "inform7/Chapter 20/Runtime Support for Tables.w"
if (Kinds__can_exchange(K)) bits += TB_COLUMN_CANEXCHANGE;
if (Kinds__uses_signed_comparisons(K)) bits += TB_COLUMN_SIGNED;
if (Kinds__uses_pointer_values(K)) bits += TB_COLUMN_ALLOCATED;
if (Kinds__eq(K, K_understanding)) bits = TB_COLUMN_TOPIC;
if (Kinds__requires_blanks_bitmap(K) == FALSE) bits += TB_COLUMN_NOBLANKBITS;
if (t->preserve_row_order_at_run_time) bits += TB_COLUMN_DONTSORTME;
WRITE("$%04x ", Data__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 20/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 168 "inform7/Chapter 20/Runtime Support for Tables.w"
current_sentence = cell;
WRITE("(");
if (Parser__Nodes__int_annotation(cell, table_cell_unspecified_ANNOT)) {
{
#line 207 "inform7/Chapter 20/Runtime Support for Tables.w"
if (t->fill_in_blanks == FALSE) WRITE(" TABLE_NOVALUE");
else Kinds__compile_default_value(OUT, K, -1, -1, "table entry");
}
#line 171 "inform7/Chapter 20/Runtime Support for Tables.w"
;
} else {
if (bits & TB_COLUMN_TOPIC)
Plugins__Parsing__compile_understanding(OUT,
cell->word_ref1, cell->word_ref2, TRUE);
else {
specification *val = Parser__Nodes__get_evaluation(cell);
if (Specifications__Values__is_generic_CONSTANT(val)) WRITE("nothing");
else if (val == NULL) internal_error("Valueless cell");
else Specifications__compile_constant_to_kind(OUT, val, K);
}
}
WRITE(") ");
words_used++;
}
#line 100 "inform7/Chapter 20/Runtime Support for Tables.w"
;
{
#line 120 "inform7/Chapter 20/Runtime Support for Tables.w"
if ((bits & TB_COLUMN_NOBLANKBITS) == 0) {
e++; if ((e % 8) == 0) blanks_array_hwm++;
}
}
#line 101 "inform7/Chapter 20/Runtime Support for Tables.w"
;
words_used++;
}
int br;
for (br = 0; br < t->blank_rows; br++) {
{
#line 207 "inform7/Chapter 20/Runtime Support for Tables.w"
if (t->fill_in_blanks == FALSE) WRITE(" TABLE_NOVALUE");
else Kinds__compile_default_value(OUT, K, -1, -1, "table entry");
}
#line 106 "inform7/Chapter 20/Runtime Support for Tables.w"
;
{
#line 120 "inform7/Chapter 20/Runtime Support for Tables.w"
if ((bits & TB_COLUMN_NOBLANKBITS) == 0) {
e++; if ((e % 8) == 0) blanks_array_hwm++;
}
}
#line 107 "inform7/Chapter 20/Runtime Support for Tables.w"
;
words_used++;
}
{
#line 127 "inform7/Chapter 20/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 110 "inform7/Chapter 20/Runtime Support for Tables.w"
;
WRITE(";\n");
}
#line 43 "inform7/Chapter 20/Runtime Support for Tables.w"
;
t->approximate_array_space_needed = words_used;
}
#line 33 "inform7/Chapter 20/Runtime Support for Tables.w"
;
END_COMPILATION_MODE;
}
#line 17 "inform7/Chapter 20/Runtime Support for Tables.w"
;
{
#line 213 "inform7/Chapter 20/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__requires_blanks_bitmap(Data__Tables__Columns__get_kind(tc)) == FALSE)
continue;
int current_bit = 1, byte_so_far = 0;
{
#line 236 "inform7/Chapter 20/Runtime Support for Tables.w"
parse_node *cell;
for (cell = t->columns[j].entries->down; cell; cell = cell->next) {
if ((Parser__Nodes__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 258 "inform7/Chapter 20/Runtime Support for Tables.w"
WRITE("$%02x ", byte_so_far);
byte_so_far = 0; current_bit = 1;
}
#line 242 "inform7/Chapter 20/Runtime Support for Tables.w"
;
}
}
#line 225 "inform7/Chapter 20/Runtime Support for Tables.w"
;
{
#line 248 "inform7/Chapter 20/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 258 "inform7/Chapter 20/Runtime Support for Tables.w"
WRITE("$%02x ", byte_so_far);
byte_so_far = 0; current_bit = 1;
}
#line 252 "inform7/Chapter 20/Runtime Support for Tables.w"
;
}
}
#line 226 "inform7/Chapter 20/Runtime Support for Tables.w"
;
if (current_bit != 1)
{
#line 258 "inform7/Chapter 20/Runtime Support for Tables.w"
WRITE("$%02x ", byte_so_far);
byte_so_far = 0; current_bit = 1;
}
#line 227 "inform7/Chapter 20/Runtime Support for Tables.w"
;
WRITE(" ! Column %d\n ", j);
}
}
WRITE("\n ! End of table\n NULL NULL;\n");
}
#line 18 "inform7/Chapter 20/Runtime Support for Tables.w"
;
{
#line 267 "inform7/Chapter 20/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 20/Runtime Support for Tables.w"
;
Data__Tables__Columns__compile_run_time_support(OUT);
{
#line 277 "inform7/Chapter 20/Runtime Support for Tables.w"
table *t;
LOOP_OVER(t, table)
if (t->amendment_of == FALSE)
Code__VirtualMachines__note_usage("table",
t->headline_fragment->word_ref1, t->headline_fragment->word_ref2,
NULL, t->approximate_array_space_needed, 0, FALSE);
}
#line 21 "inform7/Chapter 20/Runtime Support for Tables.w"
;
}
#line 288 "inform7/Chapter 20/Runtime Support for Tables.w"
void Data__Tables__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);
Text__print_raw_text_to_stream(
t->headline_fragment->word_ref1, t->headline_fragment->word_ref2, OUT);
WRITE("\"; return;\n");
}
}
#line 308 "inform7/Chapter 20/Runtime Support for Tables.w"
int rankings_table_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 310 "inform7/Chapter 20/Runtime Support for Tables.w"
#line 319 "inform7/Chapter 20/Runtime Support for Tables.w"
void Data__Tables__compile_max_score(OUTPUT_STREAM) {
table *t;
LOOP_OVER(t, table) {
int tn1 = t->table_name_w1, tn2 = t->table_name_w2;
if ((parse_nt_against_word_range(rankings_table_name_NTM, tn1, tn2, NULL, NULL)) &&
(t->no_columns >= 2) &&
(Kinds__eq(Data__Tables__kind_of_ith_column(t, 0), K_number)) &&
(Kinds__eq(Data__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) &&
(Data__NonlocalVariables__has_initial_value_set(max_score_VAR) == FALSE))
Parser__Assertions__initialise_global_variable(
max_score_VAR, Parser__Nodes__get_evaluation(PN));
}
}
if (Data__NonlocalVariables__has_initial_value_set(max_score_VAR)) {
WRITE("Global MAX_SCORE = ");
Data__NonlocalVariables__compile_initial_value(OUT, max_score_VAR);
WRITE(";\n");
}
}
#line 31 "inform7/Chapter 20/Tables of Definitions.w"
int defined_by_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 40 "inform7/Chapter 20/Tables of Definitions.w"
*X = FALSE;
Problems__sentence_problem(_P_(C20TableDefiningObject),
"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 33 "inform7/Chapter 20/Tables of Definitions.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
case 3:
{
#line 50 "inform7/Chapter 20/Tables of Definitions.w"
*X = FALSE;
{
#line 56 "inform7/Chapter 20/Tables of Definitions.w"
Problems__sentence_problem(_P_(C20TableDefiningTheImpossible),
"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 51 "inform7/Chapter 20/Tables of Definitions.w"
;
}
#line 35 "inform7/Chapter 20/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 36 "inform7/Chapter 20/Tables of Definitions.w"
#line 64 "inform7/Chapter 20/Tables of Definitions.w"
int defined_by_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 71 "inform7/Chapter 20/Tables of Definitions.w"
*X = FALSE;
Problems__sentence_problem(_P_(C20TableUndefined),
"you can only use 'defined by' in terms of a table",
"which lists the value names in the first column.");
}
#line 66 "inform7/Chapter 20/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 67 "inform7/Chapter 20/Tables of Definitions.w"
#line 99 "inform7/Chapter 20/Tables of Definitions.w"
sentence_handler DEFINED_BY_SH_handler =
{ SENTENCE_NT, DEFINED_BY_VB, 0, kind_defined_by_table };
#line 107 "inform7/Chapter 20/Tables of Definitions.w"
void kind_defined_by_table(parse_node *pn) {
int ltw1 = pn->down->next->next->word_ref1, ltw2 = pn->down->next->next->word_ref2;
int spw1 = pn->down->next->word_ref1, spw2 = pn->down->next->word_ref2;
LOGIF(TABLES, "Traverse %d: I now want to define <$W> by table <$W>\n",
traverse, spw1, spw2, ltw1, ltw2);
parse_nt_against_word_range(defined_by_sentence_object_NTM, ltw1, ltw2, NULL, NULL); if (most_recent_result == FALSE) return;
table *t = table_spec_to_table(most_recent_result_p);
if (traverse == 1) {
int abstract = NOT_APPLICABLE;
kind *K = NULL;
{
#line 133 "inform7/Chapter 20/Tables of Definitions.w"
parse_nt_against_word_range(defined_by_sentence_subject_NTM, spw1, spw2, NULL, NULL); if (most_recent_result == FALSE) return;
specification *what = most_recent_result_p;
if (Specifications__Values__is_generic_CONSTANT(what)) {
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;
K = Specifications__get_kind(what);
} else if (Specifications__species_is(what, DESCRIPTION_SPC)) {
{
#line 189 "inform7/Chapter 20/Tables of Definitions.w"
if (Calculus__Propositions__contains_quantifier(
Specifications__get_proposition(what))) {
Problems__sentence_problem(_P_(C20TableOfQuantifiedKind),
"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 143 "inform7/Chapter 20/Tables of Definitions.w"
;
abstract = FALSE;
K = Specifications__get_kind_referred_to(what);
} else {
LOG("Error at: $X", what);
{
#line 56 "inform7/Chapter 20/Tables of Definitions.w"
Problems__sentence_problem(_P_(C20TableDefiningTheImpossible),
"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 148 "inform7/Chapter 20/Tables of Definitions.w"
;
return;
}
t->first_column_by_definition = TRUE;
t->where_used_to_define = pn->down->next;
}
#line 119 "inform7/Chapter 20/Tables of Definitions.w"
;
{
#line 157 "inform7/Chapter 20/Tables of Definitions.w"
if ((Kinds__le(K, K_object) == FALSE) &&
(Kinds__has_named_constant_values(K) == FALSE)) {
LOG("K is $u\n", K);
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__handmade_problem(_P_(C20TableOfBuiltInKind));
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__has_named_constant_values(K)) &&
(Kinds__is_uncertainly_defined(K) == FALSE)) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__handmade_problem(_P_(C20TableOfExistingKind));
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 120 "inform7/Chapter 20/Tables of Definitions.w"
;
K = Kinds__weaken(K);
t->kind_defined_in_this_table = K;
Data__Tables__Columns__set_kind(t->columns[0].column_identity, t, K);
{
#line 224 "inform7/Chapter 20/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++) {
int nw1 = name_entry->word_ref1, nw2 = name_entry->word_ref2;
LOGIF(TABLES, "So I want to create: <$W>\n", nw1, nw2);
if (parse_nt_against_word_range(table_cell_blank_NTM, nw1, nw2, NULL, NULL))
{
#line 262 "inform7/Chapter 20/Tables of Definitions.w"
if (blank_objections == 0) {
Problems__quote_number(4, &row_count);
Problems__table_problem(_P_(C20TableWithBlankNames),
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 231 "inform7/Chapter 20/Tables of Definitions.w"
;
specification *evaluation = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, name_entry->word_ref1, name_entry->word_ref2, NULL, NULL))
evaluation = most_recent_result_p;
Parser__Nodes__noun_from_value(name_entry, evaluation);
if (Specifications__is_generic(evaluation))
{
#line 278 "inform7/Chapter 20/Tables of Definitions.w"
Problems__quote_number(4, &row_count);
Problems__table_problem(_P_(C20TableEntryGeneric),
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 237 "inform7/Chapter 20/Tables of Definitions.w"
;
if ((evaluation) && (Specifications__is_UNKNOWN(evaluation) == FALSE))
{
#line 288 "inform7/Chapter 20/Tables of Definitions.w"
LOG("Existing meaning was: $S\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__handmade_problem(_P_(C20TableCreatedClash));
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 239 "inform7/Chapter 20/Tables of Definitions.w"
;
Parser__Sentences__NPs__annotate_by_articles(name_entry);
Problems__redirect_problem_sentence(current_sentence, name_entry, pn->down->next);
Parser__Assertions__make_assertion(name_entry, pn->down->next);
Problems__redirect_problem_sentence(NULL, NULL, NULL);
name_entry->word_ref1 = nw1; name_entry->word_ref2 = nw2;
evaluation = NULL;
if (parse_nt_against_word_range(k_kind_NTM, nw1, nw2, NULL, NULL))
evaluation = Specifications__Values__new_generic_CONSTANT(most_recent_result_p);
else if (parse_nt_against_word_range(spec_type_expression_NTM, name_entry->word_ref1, name_entry->word_ref2, NULL, NULL))
evaluation = most_recent_result_p;
Parser__Nodes__noun_from_value(name_entry, evaluation);
if (Parser__Nodes__get_subject(name_entry) == NULL)
{
#line 305 "inform7/Chapter 20/Tables of Definitions.w"
LOG("Eval is $S\n", evaluation);
Problems__quote_source(4, name_entry);
Problems__quote_number(5, &row_count);
Problems__table_problem(_P_(C20TableDefiningNothing),
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 254 "inform7/Chapter 20/Tables of Definitions.w"
;
}
if (objections > 0) return;
}
#line 125 "inform7/Chapter 20/Tables of Definitions.w"
;
}
{
#line 324 "inform7/Chapter 20/Tables of Definitions.w"
int i;
for (i=1; i<t->no_columns; i++) {
property *P = NULL;
{
#line 344 "inform7/Chapter 20/Tables of Definitions.w"
int pw1 = t->columns[i].column_identity->word_ref1,
pw2 = t->columns[i].column_identity->word_ref2;
parse_nt_against_word_range(unfortunate_table_column_property_NTM, pw1, pw2, NULL, NULL);
P = Properties__Valued__obtain(pw1, pw2);
if (Properties__Valued__kind(P) == NULL) {
kind *CK = Data__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__eq(K1, K_value)) && (Kinds__eq(K1, K_value))) {
CK = Kinds__binary_construction(
Kinds__get_construct(CK), K_action_name, K_nil);
Data__Tables__Columns__set_kind(t->columns[i].column_identity, t, CK);
}
}
if (CK) Properties__Valued__set_kind(P, CK);
}
}
#line 327 "inform7/Chapter 20/Tables of Definitions.w"
;
if (traverse == 1)
Calculus__Propositions__assert_true_about(
Calculus__Propositions__to_provide_property(P),
Kinds__as_subject(t->kind_defined_in_this_table),
prevailing_mood);
if (t->contains_property_values_at_run_time)
{
#line 393 "inform7/Chapter 20/Tables of Definitions.w"
if (traverse == 1)
Properties__Implementation__OfValues__pp_set_table_storage(t->allocation_id, i);
}
#line 334 "inform7/Chapter 20/Tables of Definitions.w"
else
{
#line 400 "inform7/Chapter 20/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__redirect_problem_sentence(current_sentence, name_entry, data_entry);
{
#line 417 "inform7/Chapter 20/Tables of Definitions.w"
inference_subject *subj = Parser__Nodes__get_subject(name_entry);
if (traverse == 2) {
int w1 = data_entry->word_ref1, w2 = data_entry->word_ref2;
if ((w1 >= 0) && (w2 >= w1) && (parse_nt_against_word_range(table_cell_blank_NTM, w1, w2, NULL, NULL) == FALSE)) {
specification *val = Parser__Nodes__get_evaluation(data_entry);
if (Specifications__is_UNKNOWN(val)) {
if (problem_count == 0) internal_error("misevaluated cell");
} else {
Parser__Nodes__noun_from_value(data_entry, val);
Parser__Assertions__assert_property_value_from_property_subtree_infs(
P, subj, data_entry);
}
}
}
}
#line 407 "inform7/Chapter 20/Tables of Definitions.w"
;
}
Problems__redirect_problem_sentence(current_sentence, NULL, NULL);
}
#line 335 "inform7/Chapter 20/Tables of Definitions.w"
;
}
}
#line 127 "inform7/Chapter 20/Tables of Definitions.w"
;
}
#line 368 "inform7/Chapter 20/Tables of Definitions.w"
int unfortunate_table_column_property_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 374 "inform7/Chapter 20/Tables of Definitions.w"
*X = NEW_TC_PROBLEM;
Problems__quote_words(3, w1, w2);
Problems__table_problem(_P_(C20TableColumnLocation),
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 369 "inform7/Chapter 20/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 370 "inform7/Chapter 20/Tables of Definitions.w"
#line 12 "inform7/Chapter 20/Listed-In Relations.w"
void Data__Tables__Relations__create_initial_stock(void) {
}
#line 28 "inform7/Chapter 20/Listed-In Relations.w"
binary_predicate *Data__Tables__Relations__make_listed_in_predicate(table_column *tc) {
binary_predicate *bp = Semantics__BPs__make_pair(LISTED_IN_KBP,
Semantics__BPs__Terms__new(NULL),
Semantics__BPs__Terms__new(Kinds__as_subject(K_table)),
"listed_in", "lists-in", NULL, NULL,
Code__Schemas__new("(ct_1=ExistsTableRowCorr(ct_0=*2,%d,*1))",
Data__Tables__Columns__get_id(tc)),
Text__Words__lit_0());
bp->a_listed_in_predicate = TRUE;
return bp;
}
#line 48 "inform7/Chapter 20/Listed-In Relations.w"
void Data__Tables__Relations__supply_kind_for_listed_in_tc(binary_predicate *bp, kind *K) {
Semantics__BPs__Terms__set_domain(&(bp->term_details[0]), K);
Semantics__BPs__Terms__set_domain(&(bp->reversal->term_details[1]), K);
}
#line 57 "inform7/Chapter 20/Listed-In Relations.w"
void Data__Tables__Relations__create_second_stock(void) {
}
#line 63 "inform7/Chapter 20/Listed-In Relations.w"
int Data__Tables__Relations__typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
return DECLINE_TO_MATCH;
}
#line 72 "inform7/Chapter 20/Listed-In Relations.w"
int Data__Tables__Relations__assert(binary_predicate *bp,
inference_subject *infs0, specification *spec0,
inference_subject *infs1, specification *spec1) {
return FALSE;
}
#line 84 "inform7/Chapter 20/Listed-In Relations.w"
int Data__Tables__Relations__compile(int task, binary_predicate *bp, annotated_i6_schema *asch) {
if (task == TEST_ATOM_TASK) Code__LocalVariables__add_table_lookup();
return FALSE;
}
#line 92 "inform7/Chapter 20/Listed-In Relations.w"
int Data__Tables__Relations__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
WRITE("the listed in relation");
return TRUE;
}
#line 129 "inform7/Chapter 21/Equations.w"
sentence_handler EQUATION_SH_handler = { EQUATION_NT, -1, 0, NULL };
#line 132 "inform7/Chapter 21/Equations.w"
void Data__Equations__traverse_to_create(void) {
parse_node *p;
TREE_LOOP(p)
if (Parser__Nodes__type(p) == EQUATION_NT)
Data__Equations__new(p->word_ref1, p->word_ref2, FALSE);
}
#line 142 "inform7/Chapter 21/Equations.w"
int equation_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 204 "inform7/Chapter 21/Equations.w"
*X = 0;
Problems__sentence_problem(_P_(C21EquationMisnumbered),
"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 146 "inform7/Chapter 21/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 147 "inform7/Chapter 21/Equations.w"
#line 159 "inform7/Chapter 21/Equations.w"
equation *Data__Equations__new(int w1, int w2, 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_w1 = -1; eqn->where_w2 = -1;
eqn->usage_w1 = -1; eqn->usage_w2 = -1;
eqn->parsed_equation = NULL;
eqn->symbol_list = NULL;
eqn->examined_already = FALSE;
Formats__Inform6__compose_identifier(eqn->eqn_I6_identifier, 'E', eqn->allocation_id,
eqn->equation_name_w1, eqn->equation_name_w2);
int num1 = -1, num2 = -1, name1 = -1, name2 = -1;
if (anonymous == FALSE) {
{
#line 214 "inform7/Chapter 21/Equations.w"
int i, tw1, tw2;
i = Text__last_word_of_formatted_text(w1, w2, FALSE);
tw1 = w1; tw2 = i; w1 = i+1;
if (parse_nt_against_word_range(equation_name_NTM, tw1, tw2, NULL, NULL)) {
switch (most_recent_result) {
case 0: return NULL;
case 1: GET_RW(equation_name_NTM, 1, num1, num2); break;
case 2: GET_RW(equation_name_NTM, 1, name1, name2); break;
case 3:
GET_RW(equation_name_NTM, 1, num1, num2);
GET_RW(equation_name_NTM, 2, name1, name2);
break;
}
} else internal_error("malformed equation sentence");
}
#line 178 "inform7/Chapter 21/Equations.w"
;
{
#line 246 "inform7/Chapter 21/Equations.w"
if (num1 >= 0)
Semantics__Nouns__ExcerptMeanings__register_assemblage(EQUATION_MC, 0,
Text__Languages__merge(equation_names_construction_NTM, 0,
Text__Words__from_range(num1, num2)),
STORE_POINTER_equation(eqn));
if (name1 >= 0) {
if (parse_nt_against_word_range(spec_type_expression_or_value_NTM, name1, name2, NULL, NULL)) {
Problems__quote_words_as_source(1, name1, name2);
Problems__handmade_problem(_P_(C21EquationMisnamed));
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(EQUATION_MC, 0, name1, name2,
STORE_POINTER_equation(eqn));
Semantics__Nouns__ExcerptMeanings__register_assemblage(EQUATION_MC, 0,
Text__Languages__merge(equation_names_construction_NTM, 0,
Text__Words__from_range(name1, name2)),
STORE_POINTER_equation(eqn));
}
}
}
#line 179 "inform7/Chapter 21/Equations.w"
;
if (parse_nt_against_word_range(equation_where_NTM, w1, w2, NULL, NULL)) {
int v1, v2;
GET_RW(equation_where_NTM, 1, w1, w2);
GET_RW(equation_where_NTM, 2, v1, v2);
Data__Equations__set_wherewithal(eqn, v1, v2);
}
}
eqn->equation_no_w1 = num1; eqn->equation_no_w2 = num2;
eqn->equation_name_w1 = name1; eqn->equation_name_w2 = name2;
if (compare_word(w2, COMMA_V)) w2--;
eqn->word_ref1 = w1; eqn->word_ref2 = w2;
return eqn;
}
#line 239 "inform7/Chapter 21/Equations.w"
int equation_names_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 242 "inform7/Chapter 21/Equations.w"
#line 278 "inform7/Chapter 21/Equations.w"
void Data__Equations__set_wherewithal(equation *eqn, int w1, int w2) {
eqn->where_w1 = w1; eqn->where_w2 = w2;
}
#line 287 "inform7/Chapter 21/Equations.w"
void Data__Equations__traverse_to_stock(void) {
equation *eqn;
LOOP_OVER(eqn, equation) {
current_sentence = eqn->equation_created_at;
Data__Equations__examine(eqn);
}
}
#line 302 "inform7/Chapter 21/Equations.w"
void Data__Equations__examine(equation *eqn) {
if (eqn->examined_already) return;
eqn->examined_already = TRUE;
if (eqn_declare_symbols(eqn) == FALSE) return;
eqn_declare_standard_symbols();
eqn->parsed_equation = eqn_parse(eqn);
if (eqn->parsed_equation == NULL) return;
if (eqn_typecheck(eqn) == FALSE) log_equation_node(eqn->parsed_equation);
}
#line 322 "inform7/Chapter 21/Equations.w"
int equation_where_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 324 "inform7/Chapter 21/Equations.w"
#line 329 "inform7/Chapter 21/Equations.w"
int eqn_declare_symbols(equation *eqn) {
if (eqn->where_w1 < 0) return TRUE;
int result = eqn_declare_variables_inner(eqn, eqn->where_w1, eqn->where_w2, FALSE);
equation_symbol *ev;
for (ev = eqn->symbol_list; ev; ev = ev->next)
if (ev->var_kind == NULL) {
if (ev->next == NULL) {
Problems__equation_symbol_problem(_P_(BelievedImpossible),
eqn, eqn->where_w1, eqn->where_w2,
"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;
}
}
return result;
}
#line 365 "inform7/Chapter 21/Equations.w"
equation *equation_being_declared = NULL;
int equation_declared_temporarily = FALSE;
int eq_symbol_wn = -1;
#line 381 "inform7/Chapter 21/Equations.w"
int equation_where_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; eq_symbol_wn = w1; 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 385 "inform7/Chapter 21/Equations.w"
int equation_where_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 389 "inform7/Chapter 21/Equations.w"
int equation_where_setting_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; if (!preform_lookahead_mode) eqn_dec_var(equation_being_declared, 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 392 "inform7/Chapter 21/Equations.w"
int equation_where_setting_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 410 "inform7/Chapter 21/Equations.w"
*X = EQW_IDENTIFIES_PROBLEM;
if (!preform_lookahead_mode)
Problems__equation_symbol_problem(_P_(C21EquationSymbolNonValue),
equation_being_declared, R[1], R[1],
"this has neither a kind of value nor an actual value.");
}
#line 396 "inform7/Chapter 21/Equations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 419 "inform7/Chapter 21/Equations.w"
*X = EQW_IDENTIFIES_PROBLEM;
if (!preform_lookahead_mode)
Problems__equation_symbol_problem(_P_(C21EquationSymbolEqualsKOV),
equation_being_declared, R[1], R[1],
"'is' should be used, not '=', for a kind of value rather "
"than an actual value.");
}
#line 397 "inform7/Chapter 21/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 410 "inform7/Chapter 21/Equations.w"
*X = EQW_IDENTIFIES_PROBLEM;
if (!preform_lookahead_mode)
Problems__equation_symbol_problem(_P_(C21EquationSymbolNonValue),
equation_being_declared, R[1], R[1],
"this has neither a kind of value nor an actual value.");
}
#line 399 "inform7/Chapter 21/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 401 "inform7/Chapter 21/Equations.w"
int equation_symbol_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 429 "inform7/Chapter 21/Equations.w"
*X = -1;
if (!preform_lookahead_mode)
Problems__equation_symbol_problem(_P_(C21EquationSymbolMalformed),
equation_being_declared, w1, w2,
"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 404 "inform7/Chapter 21/Equations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 441 "inform7/Chapter 21/Equations.w"
*X = -1;
if (!preform_lookahead_mode)
Problems__sentence_problem(_P_(C21EquationSymbolMisdeclared),
"the symbols here are not declared properly",
"and should each be declared with a kind of value or else an "
"actual value.");
}
#line 405 "inform7/Chapter 21/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 406 "inform7/Chapter 21/Equations.w"
#line 456 "inform7/Chapter 21/Equations.w"
int eqn_declare_variables_inner(equation *eqn, int w1, int w2, int temp) {
equation_being_declared = eqn;
equation_declared_temporarily = temp;
int pc = problem_count;
parse_nt_against_word_range(equation_where_list_NTM, w1, w2, NULL, NULL);
if (problem_count > pc) return FALSE;
return TRUE;
}
int eqn_dec_var(equation *eqn, int wn, int X, void *XP) {
specification *spec = NULL;
kind *K = NULL;
int temp = equation_declared_temporarily;
if ((X == EQW_IDENTIFIES_PROBLEM) || (wn < 0)) return FALSE;
if (X != EQW_IDENTIFIES_NOTHING)
{
#line 492 "inform7/Chapter 21/Equations.w"
spec = NULL;
if (X == EQW_IDENTIFIES_KIND) {
K = XP;
if (temp) {
Problems__equation_symbol_problem(_P_(C21EquationSymbolVague), eqn, wn, wn,
"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__evaluates_to(spec);
}
if ((K) && (Kinds__is_quasinumerical(K) == FALSE)) {
Problems__equation_symbol_problem(_P_(C21EquationSymbolNonNumeric), eqn, wn, wn,
"this has a kind of value on which arithmetic cannot be done, "
"so it can have no place in an equation.");
return FALSE;
}
}
#line 471 "inform7/Chapter 21/Equations.w"
;
if (temp)
{
#line 521 "inform7/Chapter 21/Equations.w"
equation_symbol *ev;
for (ev = eqn->symbol_list; ev; ev = ev->next)
if (strcmp(Text__word_raw_text(wn), ev->variable_name) == 0) {
if (Kinds__eq(K, ev->var_kind) == FALSE) {
Problems__equation_symbol_problem(_P_(C21EquationSymbolBadSub), eqn, wn, wn,
"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__equation_symbol_problem(_P_(C21EquationSymbolSpurious), eqn, wn, wn,
"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 473 "inform7/Chapter 21/Equations.w"
else eqn_add_symbol(eqn, wn, K, spec);
return TRUE;
}
#line 544 "inform7/Chapter 21/Equations.w"
void eqn_remove_temp_variables(equation *eqn) {
equation_symbol *ev;
for (ev = eqn->symbol_list; ev; ev = ev->next)
if (ev->temp_constant) {
ev->var_const = NULL;
ev->temp_constant = FALSE;
}
}
#line 566 "inform7/Chapter 21/Equations.w"
void Data__Equations__declare_local_variables(equation *eqn) {
Code__LocalVariables__make_available_to_equation(eqn);
}
/* which calls the following for each current local variable in turn: */
void Data__Equations__declare_local(equation *eqn, int w1, int w2, kind *K) {
if (w1 != w2) return;
if ((equation_symbol_legal(w1, w2)) && (Kinds__is_quasinumerical(K)))
eqn_add_symbol(eqn, w1, K, NULL);
}
#line 583 "inform7/Chapter 21/Equations.w"
void eqn_declare_standard_symbols(void) {
if (standard_equation_symbols) return;
char text_of_constants[16];
strcpy(text_of_constants, "e pi "); /* |NO_ADDED_REAL_CONSTANTS| of these */
Text__feed_into_lexer(text_of_constants, FALSE, NULL);
int w = lexer_wordcount-NO_ADDED_REAL_CONSTANTS, i;
for (i = w; i < w+NO_ADDED_REAL_CONSTANTS; i++) {
if (parse_nt_against_word_range(spec_type_expression_NTM, i, i, NULL, NULL)) {
specification *spec = most_recent_result_p;
eqn_add_symbol(NULL, i, K_real_number, spec);
}
}
phrase *ph;
LOOP_OVER(ph, phrase) {
int w = Code__Phrases__Usage__get_equation_form(&(ph->usage_data));
if (w >= 0) {
equation_symbol *ev = eqn_add_symbol(NULL, w, K_real_number, NULL);
ev->function_notated = ph;
}
}
}
#line 610 "inform7/Chapter 21/Equations.w"
equation_symbol *eqn_add_symbol(equation *eqn, int w1, kind *K, specification *spec) {
char *name = Text__word_raw_text(w1);
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 (strcmp(name, ev->variable_name) == 0)
return ev;
ev = CREATE(equation_symbol);
strcpy(ev->variable_name, name);
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->variable_wn = w1;
ev->temp_constant = FALSE;
return ev;
}
#line 640 "inform7/Chapter 21/Equations.w"
int valid_equation_symbol_NTMR(int w1, int w2, int *X, void **XP) {
#line 641 "inform7/Chapter 21/Equations.w"
if (equation_symbol_legal(w1, w2)) { *X = w1; return TRUE; }
return FALSE;
}
#line 648 "inform7/Chapter 21/Equations.w"
int equation_symbol_legal(int w1, int w2) {
if ((w2 == w1) && (w1 >= 0)) {
char *p = Text__word_raw_text(w1);
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 670 "inform7/Chapter 21/Equations.w"
equation_node *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__Generalised__new(K_value); /* unknown for now */
enode->gK_after = Kinds__Generalised__new(K_value); /* unknown for now */
return enode;
}
#line 687 "inform7/Chapter 21/Equations.w"
equation_node *enode_new_op(int op) {
equation_node *enode = enode_new(OPERATION_EQN);
enode->eqn_operation = op;
return enode;
}
equation_node *enode_new_symbol(equation_symbol *ev) {
equation_node *enode = enode_new(SYMBOL_EQN);
enode->leaf_symbol = ev;
return enode;
}
equation_node *enode_new_constant(specification *spec) {
equation_node *enode = enode_new(CONSTANT_EQN);
enode->leaf_constant = spec;
return enode;
}
#line 709 "inform7/Chapter 21/Equations.w"
void log_equation_node(equation_node *tok) {
log_equation_node_inner(tok, 0);
}
void log_equation_node_inner(equation_node *tok, int d) {
int i;
for (i=0; i<d; i++) if (i+1<d) LOG(" "); else LOG("+---");
if (tok == NULL) LOG("<NULL>\n");
else 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 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;
}
LOG("\n");
for (i=0; i<tok->enode_arity; i++)
log_equation_node_inner(tok->enode_operands[i], d+1);
} else if (tok->eqn_type == SYMBOL_EQN) LOG("<symbol-%s>\n", tok->leaf_symbol->variable_name);
else if (tok->eqn_type == CONSTANT_EQN) LOG("<constant-$S>\n", tok->leaf_constant);
else if (tok->eqn_type == OPEN_BRACKET_EQN) LOG("<open-bracket>\n");
else if (tok->eqn_type == CLOSE_BRACKET_EQN) LOG("<close-bracket>\n");
else if (tok->eqn_type == END_EQN) LOG("<end>\n");
else LOG("<bad-eqn>\n");
}
#line 756 "inform7/Chapter 21/Equations.w"
equation_node *eqn_parse(equation *eqn) {
int w1 = eqn->word_ref1, w2 = eqn->word_ref2;
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 = w1, i = 0; char *p = NULL;
while ((wn <= w2) || (p)) {
if (p == NULL) { i = 0; p = Text__word_raw_text(wn++); }
/* we are now at character |i| in string |p|, while |wn| is the next word */
equation_node *token = NULL;
{
#line 791 "inform7/Chapter 21/Equations.w"
char c = p[i];
if (Platform__isalpha(c))
{
#line 803 "inform7/Chapter 21/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;
equation_symbol *ev;
for (ev = standard_equation_symbols; ev; ev = ev->next)
{
#line 832 "inform7/Chapter 21/Equations.w"
if (strcmp(text_of_symbol, ev->variable_name) == 0) {
token = enode_new_symbol(ev);
i += j;
break;
}
}
#line 810 "inform7/Chapter 21/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 832 "inform7/Chapter 21/Equations.w"
if (strcmp(text_of_symbol, ev->variable_name) == 0) {
token = enode_new_symbol(ev);
i += j;
break;
}
}
#line 819 "inform7/Chapter 21/Equations.w"
;
}
if (token == NULL) {
Problems__equation_problem(_P_(C21EquationTokenUnrecognised), 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 792 "inform7/Chapter 21/Equations.w"
else if (Platform__isdigit(c))
{
#line 843 "inform7/Chapter 21/Equations.w"
int j; /* again the length of the number we try to break off */
if ((p[i] == '0') && (isdigit(p[i+1]))) {
Problems__equation_problem(_P_(C21EquationLeadingZero), 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 870 "inform7/Chapter 21/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 ((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 852 "inform7/Chapter 21/Equations.w"
;
/* now sneakily add this to the word stream, and let the S-parser read it: */
Text__feed_into_lexer(text_of_number, FALSE, NULL);
specification *spec = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, lexer_wordcount-1, lexer_wordcount-1, NULL, NULL)) spec = most_recent_result_p;
else {
Problems__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 (Specifications__Values__is_actual_CONSTANT(spec) == FALSE) return NULL;
token = enode_new_constant(spec);
}
#line 793 "inform7/Chapter 21/Equations.w"
else
{
#line 889 "inform7/Chapter 21/Equations.w"
switch (c) {
case '=': token = enode_new_op(EQUALS_OPERATION); break;
case '+': token = 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 = enode_new_op(UNARY_MINUS_OPERATION);
else
token = enode_new_op(MINUS_OPERATION); break;
case '/': token = enode_new_op(DIVIDE_OPERATION); break;
case '*': token = enode_new_op(TIMES_OPERATION); break;
case '^': token = enode_new_op(POWER_OPERATION); break;
case '(': token = enode_new(OPEN_BRACKET_EQN); bl++; break;
case ')': token = enode_new(CLOSE_BRACKET_EQN); bl--; break;
default: {
char symbol[2]; symbol[0] = c; symbol[1] = 0;
Problems__equation_problem(_P_(C21EquationOperatorUnrecognised), 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 794 "inform7/Chapter 21/Equations.w"
;
}
#line 770 "inform7/Chapter 21/Equations.w"
;
{
#line 921 "inform7/Chapter 21/Equations.w"
if (application_is_implied(previous_token, token)) {
if (enode_sr_token(eqn, enode_new_op(IMPLICIT_APPLICATION_OPERATION)) == FALSE)
{
#line 945 "inform7/Chapter 21/Equations.w"
Problems__equation_problem(_P_(C21EquationMispunctuated), eqn, "",
"this seems to be wrongly punctuated, and doesn't make sense as a "
"mathematical formula.");
return NULL;
}
#line 923 "inform7/Chapter 21/Equations.w"
;
enode_count++;
} else if (multiplication_is_implied(previous_token, token)) {
if (enode_sr_token(eqn, enode_new_op(IMPLICIT_TIMES_OPERATION)) == FALSE)
{
#line 945 "inform7/Chapter 21/Equations.w"
Problems__equation_problem(_P_(C21EquationMispunctuated), eqn, "",
"this seems to be wrongly punctuated, and doesn't make sense as a "
"mathematical formula.");
return NULL;
}
#line 927 "inform7/Chapter 21/Equations.w"
;
enode_count++;
}
if (enode_sr_token(eqn, token) == FALSE)
{
#line 945 "inform7/Chapter 21/Equations.w"
Problems__equation_problem(_P_(C21EquationMispunctuated), eqn, "",
"this seems to be wrongly punctuated, and doesn't make sense as a "
"mathematical formula.");
return NULL;
}
#line 932 "inform7/Chapter 21/Equations.w"
;
enode_count++;
if (enode_count >= MAX_ENODES_IN_EXPRESSION - 2) {
Problems__equation_problem(_P_(C21EquationTooComplex), eqn, "",
"this is too long and complex an equation.");
return NULL;
}
}
#line 771 "inform7/Chapter 21/Equations.w"
;
previous_token = token;
if (p[i] == 0) p = NULL;
}
if (enode_sr_token(eqn, enode_new(END_EQN)) == FALSE)
{
#line 945 "inform7/Chapter 21/Equations.w"
Problems__equation_problem(_P_(C21EquationMispunctuated), eqn, "",
"this seems to be wrongly punctuated, and doesn't make sense as a "
"mathematical formula.");
return NULL;
}
#line 777 "inform7/Chapter 21/Equations.w"
;
equation_node *result = enode_sr_result();
if (bl != 0) {
Problems__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 953 "inform7/Chapter 21/Equations.w"
int 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 966 "inform7/Chapter 21/Equations.w"
int 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 993 "inform7/Chapter 21/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 log_sr_stacks(void) {
int i;
LOG("SR: ");
for (i=0; i<SR_sp; i++) { LOG(" %d: ", i); log_equation_node(SR_stack[i]); }
LOG("EMITTER: ");
for (i=0; i<emitter_sp; i++) { LOG(" %d: ", i); log_equation_node(emitter_stack[i]); }
}
#line 1014 "inform7/Chapter 21/Equations.w"
void enode_sr_start(void) {
SR_stack[0] = enode_new(END_EQN);
SR_sp = 1;
emitter_sp = 0;
}
#line 1024 "inform7/Chapter 21/Equations.w"
equation_node *enode_sr_result(void) {
return emitter_stack[0];
}
#line 1048 "inform7/Chapter 21/Equations.w"
int 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 ((enode_lt(SR_stack[SR_sp-1], tok)) || (enode_eq(SR_stack[SR_sp-1], tok)))
{
#line 1073 "inform7/Chapter 21/Equations.w"
SR_stack[SR_sp++] = tok;
return TRUE;
}
#line 1057 "inform7/Chapter 21/Equations.w"
else if (enode_gt(SR_stack[SR_sp-1], tok))
{
#line 1088 "inform7/Chapter 21/Equations.w"
do { if (SR_sp <= 1) return FALSE;
if (enode_emit(SR_stack[--SR_sp]) == FALSE) return FALSE;
} while ((SR_sp >= 1) && (enode_lt(SR_stack[SR_sp-1], SR_stack[SR_sp]) == FALSE));
}
#line 1059 "inform7/Chapter 21/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 1100 "inform7/Chapter 21/Equations.w"
int 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 1140 "inform7/Chapter 21/Equations.w"
int enode_lt(equation_node *tok1, equation_node *tok2) {
int f_left = f_function(tok1), g_right = g_function(tok2);
if (f_left < g_right) return TRUE; return FALSE;
}
int enode_eq(equation_node *tok1, equation_node *tok2) {
int f_left = f_function(tok1), g_right = g_function(tok2);
if (f_left == g_right) return TRUE; return FALSE;
}
int enode_gt(equation_node *tok1, equation_node *tok2) {
int f_left = f_function(tok1), g_right = g_function(tok2);
if (f_left > g_right) return TRUE; return FALSE;
}
#line 1167 "inform7/Chapter 21/Equations.w"
int 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 1191 "inform7/Chapter 21/Equations.w"
int 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 1218 "inform7/Chapter 21/Equations.w"
int eqn_typecheck(equation *eqn) {
switch (enode_count_equals(eqn->parsed_equation)) {
case 0:
Problems__equation_problem(_P_(C21EquationDoesntEquate), 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 (enode_is_equals(eqn->parsed_equation) == FALSE) {
Problems__equation_problem(_P_(C21EquationEquatesBadly), 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__equation_problem(_P_(C21EquationEquatesMultiply), eqn, "",
"this equation seems to contain more than one equals "
"sign '='.");
return FALSE;
}
/* if (detect_real_arithmetic(eqn->parsed_equation)) */
return enode_typecheck(eqn, eqn->parsed_equation);
}
#line 1250 "inform7/Chapter 21/Equations.w"
int enode_count_equals(equation_node *tok) {
int c = 0, i;
if (tok) {
if (enode_is_equals(tok)) c++;
for (i=0; i<tok->enode_arity; i++)
c += enode_count_equals(tok->enode_operands[i]);
}
return c;
}
int 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 1273 "inform7/Chapter 21/Equations.w"
int float_terminal_nodes = FALSE;
int enode_typecheck(equation *eqn, equation_node *tok) {
int result = TRUE;
if (tok == NULL) return result;
int i;
for (i=0; i<tok->enode_arity; i++)
if (enode_typecheck(eqn, tok->enode_operands[i]) == FALSE)
result = FALSE;
if (result) {
switch (tok->eqn_type) {
case SYMBOL_EQN:
tok->gK_before =
Kinds__Generalised__new(tok->leaf_symbol->var_kind);
break;
case CONSTANT_EQN:
tok->gK_before =
Kinds__Generalised__new(
Specifications__get_kind(tok->leaf_constant));
break;
case OPERATION_EQN:
if (tok->eqn_operation == EQUALS_OPERATION)
{
#line 1317 "inform7/Chapter 21/Equations.w"
kind *L = Kinds__Generalised__underlying(tok->enode_operands[0]->gK_after);
kind *R = Kinds__Generalised__underlying(tok->enode_operands[1]->gK_after);
L = Kinds__to_integer(L);
R = Kinds__to_integer(R);
if (Kinds__eq(L, R) == FALSE) {
result = FALSE;
LOG("Tried to equate $u and $u\n", L, R);
Problems__equation_problem(_P_(C21EquationIncomparable), eqn, "",
"this equation tries to set two values equal which have "
"different kinds from each other.");
}
int lf = Kinds__Generalised__uses_floating_point(tok->enode_operands[0]->gK_after);
int rf = Kinds__Generalised__uses_floating_point(tok->enode_operands[1]->gK_after);
if ((lf == TRUE) && (rf == FALSE)) promote_subequation(eqn, tok->enode_operands[1], TRUE);
if ((lf == FALSE) && (rf == TRUE)) demote_subequation(eqn, tok->enode_operands[1]);
tok->gK_before = tok->enode_operands[0]->gK_after;
}
#line 1295 "inform7/Chapter 21/Equations.w"
else if (tok->eqn_operation == POWER_OPERATION)
{
#line 1340 "inform7/Chapter 21/Equations.w"
equation_node *base = tok->enode_operands[0];
equation_node *power = tok->enode_operands[1];
if (Kinds__Dimensions__dimensionless(Kinds__Generalised__underlying(base->gK_after))) {
tok->gK_before = base->gK_after;
} else if ((Kinds__eq(Kinds__Generalised__underlying(power->gK_after), K_number) == FALSE) ||
(power->eqn_type != CONSTANT_EQN)) {
result = FALSE;
Problems__equation_problem(_P_(C21EquationDimensionPower), 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
{
#line 1377 "inform7/Chapter 21/Equations.w"
kind *K = K_number;
kind *F =
Kinds__to_integer(
Kinds__Generalised__underlying(
base->gK_after));
int real = FALSE;
if (Kinds__Generalised__uses_floating_point(base->gK_after)) real = TRUE;
int op = TIMES_OPERATION;
int n = Specifications__Values__get_literal_value(power->leaf_constant);
if (n < 0) { n = -n; op = DIVIDE_OPERATION; }
while (n > 0) {
K = Kinds__Dimensions__arithmetic_on_kinds(K, F, op);
n--;
}
if (real)
tok->gK_before =
Kinds__Generalised__to_real(
Kinds__Generalised__new(K));
else
tok->gK_before =
Kinds__Generalised__new(K);
}
#line 1354 "inform7/Chapter 21/Equations.w"
;
int lf = Kinds__Generalised__uses_floating_point(tok->enode_operands[0]->gK_after);
int rf = Kinds__Generalised__uses_floating_point(tok->enode_operands[1]->gK_after);
if ((lf == TRUE) && (rf == FALSE)) promote_subequation(eqn, tok->enode_operands[1], FALSE);
if ((lf == FALSE) && (rf == TRUE)) promote_subequation(eqn, tok->enode_operands[0], FALSE);
}
#line 1297 "inform7/Chapter 21/Equations.w"
else if (tok->eqn_operation == IMPLICIT_APPLICATION_OPERATION)
{
#line 1363 "inform7/Chapter 21/Equations.w"
equation_node *fn = tok->enode_operands[0];
if ((fn->eqn_type == SYMBOL_EQN) && (fn->leaf_symbol->function_notated))
tok->gK_before =
Kinds__Generalised__new(
Code__Phrases__TypeData__get_return_kind(
&(fn->leaf_symbol->function_notated->type_data)));
int rf = Kinds__Generalised__uses_floating_point(tok->enode_operands[1]->gK_after);
if (rf == FALSE) promote_subequation(eqn, tok->enode_operands[1], FALSE);
}
#line 1299 "inform7/Chapter 21/Equations.w"
else
{
#line 1403 "inform7/Chapter 21/Equations.w"
kind *K = NULL;
kind *O1 =
Kinds__to_integer(
Kinds__Generalised__underlying(
tok->enode_operands[0]->gK_after));
int real = FALSE;
if (Kinds__Generalised__uses_floating_point(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__to_integer(
Kinds__Generalised__underlying(
tok->enode_operands[1]->gK_after));
if (Kinds__Generalised__uses_floating_point(tok->enode_operands[1]->gK_after))
real = TRUE;
K = Kinds__Dimensions__arithmetic_on_kinds(O1, O2, tok->eqn_operation);
int lf = Kinds__Generalised__uses_floating_point(tok->enode_operands[0]->gK_after);
int rf = Kinds__Generalised__uses_floating_point(tok->enode_operands[1]->gK_after);
if ((lf == TRUE) && (rf == FALSE)) promote_subequation(eqn, tok->enode_operands[1], FALSE);
if ((lf == FALSE) && (rf == TRUE)) promote_subequation(eqn, tok->enode_operands[0], FALSE);
}
if (K == NULL) {
result = FALSE;
tok->gK_before = Kinds__Generalised__new(K_value);
LOG("Failed at operation:\n"); log_equation_node(tok);
if (Kinds__Dimensions__arithmetic_op_is_unary(tok->eqn_operation))
{
#line 1445 "inform7/Chapter 21/Equations.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(4,
Kinds__Generalised__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 CUBEROOT_OPERATION:
Problems__quote_text(6, "taking the cube root of");
break;
}
Problems__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 1431 "inform7/Chapter 21/Equations.w"
else
{
#line 1468 "inform7/Chapter 21/Equations.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(4, Kinds__Generalised__underlying(tok->enode_operands[0]->gK_after));
Problems__quote_kind(5, Kinds__Generalised__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__handmade_problem(_P_(C21EquationBadArithmetic));
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 1433 "inform7/Chapter 21/Equations.w"
;
} else if (real)
tok->gK_before =
Kinds__Generalised__to_real(
Kinds__Generalised__new(K));
else
tok->gK_before =
Kinds__Generalised__new(K);
}
#line 1301 "inform7/Chapter 21/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))
promote_subequation(eqn, tok, FALSE);
return result;
}
#line 1502 "inform7/Chapter 21/Equations.w"
void promote_subequation(equation *eqn, equation_node *tok, int deeply) {
if (tok == NULL) return;
if (deeply) {
float_terminal_nodes = TRUE;
enode_typecheck(eqn, tok);
float_terminal_nodes = FALSE;
}
tok->gK_after = Kinds__Generalised__to_real(tok->gK_after);
}
void demote_subequation(equation *eqn, equation_node *tok) {
if (tok == NULL) return;
tok->gK_after = Kinds__Generalised__to_integer(tok->gK_after);
}
#line 1523 "inform7/Chapter 21/Equations.w"
void Data__Equations__compile(OUTPUT_STREAM) {
equation *eqn;
LOOP_OVER(eqn, equation) {
OUT = Code__Routines__begin(OUT, eqn->eqn_I6_identifier);
WRITE("return 0;\n");
OUT = Code__Routines__end(OUT);
}
}
#line 1535 "inform7/Chapter 21/Equations.w"
char *Data__Equations__identifier(equation *eqn) {
return eqn->eqn_I6_identifier;
}
#line 1546 "inform7/Chapter 21/Equations.w"
void Data__Equations__set_usage_notes(equation *eqn, int u1, int u2) {
eqn->usage_w1 = u1; eqn->usage_w2 = u2;
}
#line 1555 "inform7/Chapter 21/Equations.w"
void Data__Equations__compile_solution(OUTPUT_STREAM, int w1, int w2, equation *eqn) {
if (eqn->usage_w1 >= 0)
eqn_declare_variables_inner(eqn, eqn->usage_w1, eqn->usage_w2, TRUE);
compile_solution_inner(OUT, w1, w2, eqn);
eqn_remove_temp_variables(eqn);
eqn->usage_w1 = -1; eqn->usage_w2 = -1;
}
#line 1568 "inform7/Chapter 21/Equations.w"
void compile_solution_inner(OUTPUT_STREAM, int w1, int w2, equation *eqn) {
equation_symbol *to_solve = NULL;
{
#line 1582 "inform7/Chapter 21/Equations.w"
if (w1 == w2) {
char *p = Text__word_raw_text(w1);
equation_symbol *ev;
for (ev = eqn->symbol_list; ev; ev = ev->next)
if (strcmp(p, ev->variable_name) == 0)
to_solve = ev;
}
if (to_solve == NULL) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_words(3, eqn->word_ref1, eqn->word_ref2);
Problems__handmade_problem(_P_(C21EquationBadTarget));
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_words(2, w1, w2);
Problems__quote_words(3, eqn->word_ref1, eqn->word_ref2);
Problems__quote_spec(4, to_solve->var_const);
Problems__handmade_problem(_P_(C21EquationConstantTarget));
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 1571 "inform7/Chapter 21/Equations.w"
;
{
#line 1625 "inform7/Chapter 21/Equations.w"
if (eqn_rearrange(eqn, to_solve) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_words(3, eqn->word_ref1, eqn->word_ref2);
Problems__handmade_problem(_P_(C21EquationInsoluble));
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 (eqn_typecheck(eqn) == FALSE) return;
}
#line 1572 "inform7/Chapter 21/Equations.w"
;
{
#line 1651 "inform7/Chapter 21/Equations.w"
equation_symbol *ev;
for (ev = eqn->symbol_list; ev; ev = ev->next)
if (ev->var_const == NULL) {
ev->local_map = Code__LocalVariables__parse(Code__Frames__current_stack_frame(),
ev->variable_wn, ev->variable_wn);
if (ev->local_map == NULL)
{
#line 1669 "inform7/Chapter 21/Equations.w"
if (ev == to_solve) internal_error("can't find 'let' variable to assign");
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_words(3, eqn->word_ref1, eqn->word_ref2);
Problems__quote_words(4, ev->variable_wn, ev->variable_wn);
Problems__handmade_problem(_P_(C21EquationSymbolMissing));
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 1657 "inform7/Chapter 21/Equations.w"
else
{
#line 1694 "inform7/Chapter 21/Equations.w"
kind *K = Code__LocalVariables__kind(ev->local_map);
if (Kinds__eq(K, K_value)) {
K = ev->var_kind;
Code__LocalVariables__set_kind(ev->local_map, K);
}
if (Kinds__eq(K, ev->var_kind) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_words(3, eqn->word_ref1, eqn->word_ref2);
Problems__quote_words(4, ev->variable_wn, ev->variable_wn);
Problems__quote_kind(5, K);
Problems__quote_kind(6, ev->var_kind);
Problems__handmade_problem(_P_(C21EquationSymbolWrongKOV));
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 1659 "inform7/Chapter 21/Equations.w"
;
}
}
#line 1573 "inform7/Chapter 21/Equations.w"
;
WRITE("! Solving %s for '%s'\n", eqn->eqn_I6_identifier, to_solve->variable_name);
enode_compile(OUT, eqn, eqn->parsed_equation);
}
#line 1719 "inform7/Chapter 21/Equations.w"
void enode_compile(OUTPUT_STREAM, equation *eqn, equation_node *tok) {
int a = 0;
if (Kinds__Generalised__uses_floating_point(tok->gK_before)) a = 1;
int b = 0;
if (Kinds__Generalised__uses_floating_point(tok->gK_after)) b = 1;
int f = b - a;
if (f == 1) begin_flotation(OUT, Kinds__Generalised__underlying(tok->gK_before));
else if (f == -1) begin_deflotation(OUT, Kinds__Generalised__underlying(tok->gK_before));
switch (tok->eqn_type) {
case SYMBOL_EQN:
if (tok->leaf_symbol->var_const)
Specifications__compile(OUT, tok->leaf_symbol->var_const);
else if (tok->leaf_symbol->local_map)
WRITE("%s",
Code__LocalVariables__lvalue(tok->leaf_symbol->local_map));
else if (tok->leaf_symbol->function_notated) {
char identifier[32];
Code__Routines__ToPhrases__Requests__make_identifier(identifier,
tok->leaf_symbol->function_notated,
Code__Phrases__TypeData__kind(
&(tok->leaf_symbol->function_notated->type_data)));
WRITE("%s", identifier);
} else internal_error("uncompilable equation node");
break;
case CONSTANT_EQN:
Specifications__compile(OUT, tok->leaf_constant);
break;
case OPERATION_EQN: WRITE("(");
{
#line 1756 "inform7/Chapter 21/Equations.w"
equation_node *X = tok->enode_operands[0];
kind *KX = Kinds__Generalised__underlying(X->gK_after);
equation_node *Y = tok->enode_operands[1];
kind *KY = (Y)?(Kinds__Generalised__underlying(Y->gK_after)):NULL;
if (Kinds__Generalised__uses_floating_point(X->gK_after)) {
KX = K_real_number; KY = K_real_number;
}
Kinds__perform_arithmetic(OUT, tok->eqn_operation, eqn, NULL, X, KX, NULL, Y, KY);
}
#line 1746 "inform7/Chapter 21/Equations.w"
; WRITE(")"); break;
default: internal_error("forbidden enode found in parsed equation");
}
if (f == 1) end_flotation(OUT, Kinds__Generalised__underlying(tok->gK_before));
else if (f == -1) end_deflotation(OUT, Kinds__Generalised__underlying(tok->gK_before));
}
#line 1769 "inform7/Chapter 21/Equations.w"
void enode_compilation_error(equation *eqn, equation_node *tok) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, eqn->word_ref1, eqn->word_ref2);
Problems__handmade_problem(_P_(C21HardIntegerRoot));
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 1797 "inform7/Chapter 21/Equations.w"
int eqn_rearrange(equation *eqn, equation_symbol *to_solve) {
while (TRUE) {
{
#line 1820 "inform7/Chapter 21/Equations.w"
int lc = enode_count_var(eqn->parsed_equation->enode_operands[0], to_solve);
int rc = 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 1799 "inform7/Chapter 21/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 1884 "inform7/Chapter 21/Equations.w"
/* rearrange to move this operator */
int op = old_LHS->eqn_operation;
if (op == POWER_OPERATION)
{
#line 1942 "inform7/Chapter 21/Equations.w"
int p = Specifications__Values__get_literal_value(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] = enode_new_op(DIVIDE_OPERATION);
old_LHS->enode_operands[1]->enode_arity = 2;
old_LHS->enode_operands[1]->enode_operands[0] = enode_new_constant(
Specifications__Values__new_integer_literal(1));
old_LHS->enode_operands[1]->enode_operands[0]->gK_before =
Kinds__Generalised__new(K_number);
old_LHS->enode_operands[1]->enode_operands[0]->gK_after =
Kinds__Generalised__new(K_real_number);
old_LHS->enode_operands[1]->enode_operands[1] = the_power;
old_LHS->enode_operands[1]->gK_before =
Kinds__Generalised__new(K_real_number);
Kinds__notify_of_use(K_real_number);
}
}
#line 1887 "inform7/Chapter 21/Equations.w"
else if (op == IMPLICIT_APPLICATION_OPERATION)
{
#line 1995 "inform7/Chapter 21/Equations.w"
equation_node *fnode = old_LHS->enode_operands[0];
if ((fnode->leaf_symbol == NULL) ||
(fnode->leaf_symbol->function_notated == NULL)) {
log_equation_node(fnode);
internal_error("not a function being applied");
}
phrase *f = fnode->leaf_symbol->function_notated;
phrase *finv = Code__Phrases__Usage__get_equation_inverse(&(f->usage_data));
if (finv == NULL) return FALSE; /* no known inverse for this function */
LOG("Inverse of $R is $R\n", f, finv);
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 1889 "inform7/Chapter 21/Equations.w"
else {
int promote = 0, new_op = PLUS_OPERATION;
if (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 1807 "inform7/Chapter 21/Equations.w"
else
{
#line 2027 "inform7/Chapter 21/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:
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] = 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 1809 "inform7/Chapter 21/Equations.w"
;
}
return TRUE;
}
#line 2060 "inform7/Chapter 21/Equations.w"
int 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 += enode_count_var(tok->enode_operands[i], to_solve);
return c;
}
#line 2075 "inform7/Chapter 21/Equations.w"
void Data__Equations__internal_test(int e1, int e2) {
int wh1 = -1, wh2 = -1;
if (parse_nt_against_word_range(equation_where_NTM, e1, e2, NULL, NULL)) {
int wh1, wh2;
GET_RW(equation_where_NTM, 1, e1, e2);
GET_RW(equation_where_NTM, 2, wh1, wh2);
}
equation *eqn = Data__Equations__new(e1, e2, TRUE);
Data__Equations__set_wherewithal(eqn, wh1, wh2);
Data__Equations__examine(eqn);
Plugins__Parsing__TestScripts__Internal__begin_reporting();
log_equation_parsed(eqn);
equation_symbol *ev;
for (ev = eqn->symbol_list; ev; ev = ev->next) {
if (eqn_rearrange(eqn, ev) == FALSE)
LOG("Too hard to rearrange to solve for %s\n", ev->variable_name);
else {
LOG("Rearranged to solve for %s:\n", ev->variable_name);
log_equation_parsed(eqn);
}
}
Plugins__Parsing__TestScripts__Internal__end_reporting();
}
#line 2103 "inform7/Chapter 21/Equations.w"
void Data__Equations__log(equation *eqn) {
LOG("{$W}", eqn->word_ref1, eqn->word_ref2);
}
void log_equation_parsed(equation *eqn) {
if (eqn == NULL) LOG("<null>\n");
else log_equation_node(eqn->parsed_equation);
}
void Data__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__doc_link("EQUATIONS"); INDEX(")<p>\n");
int N = 0;
LOOP_OVER(eqn, equation) {
int mw = eqn->equation_no_w2;
if (eqn->equation_name_w2 > mw) mw = eqn->equation_name_w2;
if (mw >= 0) {
Text__print_raw_text_to_stream(eqn->equation_created_at->word_ref1, mw, ifl);
Index__link(eqn->equation_created_at->word_ref1);
INDEX(" (");
Text__print_raw_text_to_stream(eqn->word_ref1, eqn->word_ref2, ifl);
INDEX(")<br>\n");
N++;
}
}
if (N == 0) INDEX("<p><i>None</i>.</p>");
}
#line 97 "inform7/Chapter 21/Inform 6 Inclusions.w"
int inclusion_side, section_inclusion_wn, segment_inclusion_wn;
#line 110 "inform7/Chapter 21/Inform 6 Inclusions.w"
int inform6_inclusion_location_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 126 "inform7/Chapter 21/Inform 6 Inclusions.w"
*X = SEGMENT_LEVEL_INC;
inclusion_side = R[1] - 1; segment_inclusion_wn = R[2];
}
#line 111 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 132 "inform7/Chapter 21/Inform 6 Inclusions.w"
*X = SECTION_LEVEL_INC;
inclusion_side = R[1] - 1; section_inclusion_wn = R[2]; segment_inclusion_wn = R[3];
}
#line 112 "inform7/Chapter 21/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; specification_s_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 138 "inform7/Chapter 21/Inform 6 Inclusions.w"
Problems__sentence_problem(_P_(C21WhenDefiningUnknown),
"I do not understand what definition you're referring to",
"so I can't make an Inform 6 inclusion there.");
}
#line 114 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 145 "inform7/Chapter 21/Inform 6 Inclusions.w"
Problems__sentence_problem(_P_(C21BeforeTheLibrary),
"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 115 "inform7/Chapter 21/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 117 "inform7/Chapter 21/Inform 6 Inclusions.w"
int inclusion_side_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 122 "inform7/Chapter 21/Inform 6 Inclusions.w"
#line 156 "inform7/Chapter 21/Inform 6 Inclusions.w"
sentence_handler INFORM6CODE_SH_handler =
{ INFORM6CODE_NT, -1, 2, inform_6_inclusion };
void inform_6_inclusion(parse_node *PN) {
current_sentence = PN;
int iw1 = PN->word_ref1+3, iw2 = PN->word_ref2; /* the instructions */
if (iw1 > iw2)
{
#line 193 "inform7/Chapter 21/Inform 6 Inclusions.w"
Config__Template__new_intervention(1, "Output.i6t", "I6 Inclusions",
Text__word_raw_text(PN->word_ref1 + 2), NULL);
return;
}
#line 164 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
int problem = TRUE;
if (parse_nt_against_word_range(inform6_inclusion_location_NTM, iw1, iw2, NULL, NULL)) {
problem = FALSE;
switch (most_recent_result) {
case SEGMENT_LEVEL_INC:
{
#line 200 "inform7/Chapter 21/Inform 6 Inclusions.w"
Text__dequote_word(segment_inclusion_wn);
Config__Template__new_intervention(
inclusion_side, Text__word_text(segment_inclusion_wn), NULL,
Text__word_raw_text(PN->word_ref1+2), NULL);
}
#line 170 "inform7/Chapter 21/Inform 6 Inclusions.w"
; break;
case SECTION_LEVEL_INC:
{
#line 208 "inform7/Chapter 21/Inform 6 Inclusions.w"
Text__dequote_word(section_inclusion_wn);
Text__dequote_word(segment_inclusion_wn);
Config__Template__new_intervention(
inclusion_side, Text__word_text(segment_inclusion_wn),
Text__word_text(section_inclusion_wn),
Text__word_raw_text(PN->word_ref1+2), NULL);
}
#line 172 "inform7/Chapter 21/Inform 6 Inclusions.w"
; break;
case WHEN_DEFINING_INC:
{
#line 219 "inform7/Chapter 21/Inform 6 Inclusions.w"
specification *spec = specification_s_NTMV;
inference_subject *infs = World__Subjects__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 174 "inform7/Chapter 21/Inform 6 Inclusions.w"
; break;
case AS_PREFORM_INC: return;
}
}
if (problem)
{
#line 230 "inform7/Chapter 21/Inform 6 Inclusions.w"
Problems__sentence_problem(_P_(C21BadI6Inclusion),
"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 178 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
}
#line 245 "inform7/Chapter 21/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) {
Config__Template__interpret(OUT,
Text__word_raw_text(inclm->material_to_include->word_ref1 + 2), NULL, -1);
WRITE("\n");
}
}
#line 262 "inform7/Chapter 21/Inform 6 Inclusions.w"
sentence_handler USEMEANS_SH_handler =
{ SENTENCE_NT, USEMEANS_VB, 1, new_use_option };
void new_use_option(parse_node *p) {
if ((parse_nt_against_word_range(use_translates_as_sentence_object_NTM, p->down->next->next->word_ref1, p->down->next->next->word_ref2, NULL, NULL)) &&
(parse_nt_against_word_range(use_sentence_object_NTM, p->down->next->word_ref1, p->down->next->word_ref2, NULL, NULL))) {
int o1, o2;
GET_RW(use_sentence_object_NTM, 1, o1, o2);
use_option *uo = CREATE(use_option);
uo->word_ref1 = o1; uo->word_ref2 = o2;
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 ((parse_nt_against_word_range(notable_use_option_name_NTM, o1, o2, NULL, NULL)) && (most_recent_result == AUTHORIAL_MODESTY_UO))
uo->source_file_scoped = TRUE;
Semantics__Nouns__ExcerptMeanings__register(
MISCELLANEOUS_MC, USE_OPTION_SMC, uo->word_ref1, uo->word_ref2,
STORE_POINTER_use_option(uo));
}
}
#line 288 "inform7/Chapter 21/Inform 6 Inclusions.w"
int use_translates_as_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 295 "inform7/Chapter 21/Inform 6 Inclusions.w"
*X = FALSE;
Problems__sentence_problem(_P_(C21UseTranslatesNotI6),
"that translates into something which isn't a simple I6 inclusion",
"placed in '(-' and '-)' markers.");
}
#line 290 "inform7/Chapter 21/Inform 6 Inclusions.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 21/Inform 6 Inclusions.w"
#line 304 "inform7/Chapter 21/Inform 6 Inclusions.w"
use_option *parse_uo(int o1, int o2) {
meaning_list *ml = Parser__SP__parse_excerpt(MISCELLANEOUS_MC, o1, o2);
if ((ml) && (Semantics__Nouns__ExcerptMeanings__get_secondary_code(
Parser__SP__MeaningLists__meaning(ml)) == USE_OPTION_SMC))
return RETRIEVE_POINTER_use_option(
Semantics__Nouns__ExcerptMeanings__data(
Parser__SP__MeaningLists__meaning(ml)));
return NULL;
}
#line 323 "inform7/Chapter 21/Inform 6 Inclusions.w"
int use_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 328 "inform7/Chapter 21/Inform 6 Inclusions.w"
#line 334 "inform7/Chapter 21/Inform 6 Inclusions.w"
int notable_use_option_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 346 "inform7/Chapter 21/Inform 6 Inclusions.w"
#line 364 "inform7/Chapter 21/Inform 6 Inclusions.w"
sentence_handler USE_SH_handler =
{ SENTENCE_NT, USE_VB, 0, handle_set_use_option };
void handle_set_use_option(parse_node *p) {
set_use_options(p->down->next);
}
void set_use_options(parse_node *p) {
if (Parser__Nodes__type(p) == AND_NT) {
set_use_options(p->down);
set_use_options(p->down->next);
return;
}
int w1 = p->word_ref1, w2 = p->word_ref2;
if (parse_nt_against_word_range(use_sentence_object_NTM, w1, w2, NULL, NULL))
{
#line 390 "inform7/Chapter 21/Inform 6 Inclusions.w"
int min_setting = -1;
if (most_recent_result < 0)
{
#line 429 "inform7/Chapter 21/Inform 6 Inclusions.w"
int n = -most_recent_result;
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(Text__word_raw_text(w1)) > 63) {
Problems__sentence_problem(_P_(C21BadICLIdentifier),
"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, Text__word_raw_text(w1));
ms->number = n;
return;
}
#line 391 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
if (most_recent_result > 0) min_setting = most_recent_result;
int o1, o2;
GET_RW(use_sentence_object_NTM, 1, o1, o2);
use_option *uo = parse_uo(o1, o2);
if (uo) {
extension_file *ef = NULL;
{
#line 416 "inform7/Chapter 21/Inform 6 Inclusions.w"
if (uo->minimum_setting_value == -1) {
if (min_setting != -1)
Problems__sentence_problem(_P_(C21UONotNumerical),
"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 398 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
if (uo->source_file_scoped) {
ef = Text__Reader__sf_get_extension_corresponding(Text__file_of_origin(o1));
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;
}
Config__Inclusions__UseOptions__set_immediate_option_flags(o1, o2, uo);
return;
}
}
#line 379 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
if (traverse == 1) return;
Text__log(w1, w2);
Problems__sentence_problem(_P_(C21UnknownUseOption),
"that isn't a 'Use' option known to me",
"and needs to be one of the ones listed in the documentation.");
}
#line 448 "inform7/Chapter 21/Inform 6 Inclusions.w"
use_option *uo_being_set = NULL;
void Config__Inclusions__UseOptions__set_immediate_option_flags(int w1, int w2, use_option *uo) {
uo_being_set = uo;
parse_nt_against_word_range(immediate_use_NTM, w1, w2, NULL, NULL);
}
#line 460 "inform7/Chapter 21/Inform 6 Inclusions.w"
int immediate_use_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 464 "inform7/Chapter 21/Inform 6 Inclusions.w"
int immediate_use_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 468 "inform7/Chapter 21/Inform 6 Inclusions.w"
int immediate_use_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 476 "inform7/Chapter 21/Inform 6 Inclusions.w"
switch (R[1]) {
case AUTHORIAL_MODESTY_UO: {
extension_file *ef =
Text__Reader__sf_get_extension_corresponding(
Text__file_of_origin(w1));
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: Code__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;
}
}
#line 470 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
#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 21/Inform 6 Inclusions.w"
#line 506 "inform7/Chapter 21/Inform 6 Inclusions.w"
int Config__Inclusions__get_dynamic_memory_allocation(void) {
return dynamic_memory_allocation;
}
#line 513 "inform7/Chapter 21/Inform 6 Inclusions.w"
int Config__Inclusions__get_index_figure_thumbnails(void) {
return index_figure_thumbnails;
}
#line 521 "inform7/Chapter 21/Inform 6 Inclusions.w"
int uo_set_from(use_option *uo, int category, extension_file *ef) {
source_file *sf = (uo->where_used)?(Text__file_of_origin(uo->where_used->word_ref1)):NULL;
extension_file *efo = (sf)?(Text__Reader__sf_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 540 "inform7/Chapter 21/Inform 6 Inclusions.w"
void Config__Inclusions__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");
Config__Template__interpret(OUT,
Text__word_raw_text(uo->option_expansion->word_ref1 + 1),
NULL, uo->minimum_setting_value);
WRITE("\n");
}
if (existing_story_file) {
WRITE("#IFNDEF MEMORY_ECONOMY; Constant MEMORY_ECONOMY true; #ENDIF;\n");
}
}
#line 559 "inform7/Chapter 21/Inform 6 Inclusions.w"
void Config__Inclusions__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) &&
(Code__VirtualMachines__allow_MAX_LOCAL_VARIABLES() == FALSE))
continue;
WRITE("!%% $%s=%d\n", ms->ICL_identifier, ms->number);
}
}
#line 577 "inform7/Chapter 21/Inform 6 Inclusions.w"
void Config__Inclusions__UseOptions__index(void) {
INDEX("<p>The following use options are in force:</p>");
index_options_in_force_from(MAIN_TEXT_UO_ORIGIN, NULL);
index_options_in_force_from(OPTIONS_FILE_UO_ORIGIN, NULL);
extension_file *ef;
LOOP_OVER(ef, extension_file) 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>");
Formats__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 606 "inform7/Chapter 21/Inform 6 Inclusions.w"
INDEX("<span style=\"white-space:nowrap\";>");
TEMPORARY_STREAM;
STREAM_WRITE(TEMP, "Use ");
Text__print_raw_text_to_stream(uo->word_ref1, uo->word_ref2, TEMP);
STREAM_WRITE(TEMP, ".");
Formats__HTML__Javascript__paste(ifl, -1, -1, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
INDEX("&nbsp;");
Text__print_raw_text_to_stream(uo->word_ref1, uo->word_ref2, ifl);
INDEX("</span>");
}
#line 595 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
if (--nt > 0) INDEX(", ");
}
}
INDEX("</p>");
}
}
#line 620 "inform7/Chapter 21/Inform 6 Inclusions.w"
void 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) &&
(uo_set_from(uo, category, ef))) {
if (N++ == 0)
{
#line 644 "inform7/Chapter 21/Inform 6 Inclusions.w"
Formats__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__doc_link("OPTIONSFILE"); break;
case EXTENSION_UO_ORIGIN:
if (ef == standard_rules_extension) INDEX("the ");
else INDEX("the extension ");
Text__print_raw_text_to_stream(ef->name_w1, ef->name_w2, ifl);
break;
}
INDEX(":</font></p>");
}
#line 627 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
{
#line 663 "inform7/Chapter 21/Inform 6 Inclusions.w"
Formats__HTML__open_para(ifl, 3, "tight");
INDEX("Use ");
Text__print_raw_text_to_stream(uo->word_ref1, uo->word_ref2, ifl);
if (uo->minimum_setting_value >= 0) INDEX(" of at least %d", uo->minimum_setting_value);
if (uo->where_used) Index__link(uo->where_used->word_ref1);
if (uo->minimum_setting_value >= 0) {
INDEX("&nbsp;");
TEMPORARY_STREAM;
STREAM_WRITE(TEMP, "Use ");
Text__print_raw_text_to_stream(uo->word_ref1, uo->word_ref2, TEMP);
STREAM_WRITE(TEMP, " of at least %d.", 2*(uo->minimum_setting_value));
Formats__HTML__Javascript__paste(ifl, -1, -1, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
INDEX("&nbsp;<i>Double this</i>");
}
INDEX("</p>");
}
#line 628 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
}
}
LOOP_OVER(uo, use_option) {
if (uo->source_file_scoped) continue;
if (((uo->option_used) && (uo->minimum_setting_value >= 0)) &&
(uo_set_from(uo, category, ef))) {
if (N++ == 0)
{
#line 644 "inform7/Chapter 21/Inform 6 Inclusions.w"
Formats__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__doc_link("OPTIONSFILE"); break;
case EXTENSION_UO_ORIGIN:
if (ef == standard_rules_extension) INDEX("the ");
else INDEX("the extension ");
Text__print_raw_text_to_stream(ef->name_w1, ef->name_w2, ifl);
break;
}
INDEX(":</font></p>");
}
#line 635 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
{
#line 663 "inform7/Chapter 21/Inform 6 Inclusions.w"
Formats__HTML__open_para(ifl, 3, "tight");
INDEX("Use ");
Text__print_raw_text_to_stream(uo->word_ref1, uo->word_ref2, ifl);
if (uo->minimum_setting_value >= 0) INDEX(" of at least %d", uo->minimum_setting_value);
if (uo->where_used) Index__link(uo->where_used->word_ref1);
if (uo->minimum_setting_value >= 0) {
INDEX("&nbsp;");
TEMPORARY_STREAM;
STREAM_WRITE(TEMP, "Use ");
Text__print_raw_text_to_stream(uo->word_ref1, uo->word_ref2, TEMP);
STREAM_WRITE(TEMP, " of at least %d.", 2*(uo->minimum_setting_value));
Formats__HTML__Javascript__paste(ifl, -1, -1, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
INDEX("&nbsp;<i>Double this</i>");
}
INDEX("</p>");
}
#line 636 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
}
}
}
#line 685 "inform7/Chapter 21/Inform 6 Inclusions.w"
void Config__Inclusions__UseOptions__TestUseOption_routine(OUTPUT_STREAM) {
WRITE("Constant NO_USE_OPTIONS = %d;\n", NUMBER_CREATED(use_option));
{
#line 694 "inform7/Chapter 21/Inform 6 Inclusions.w"
OUT = Code__Routines__begin(OUT, "TestUseOption");
Code__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 = Code__Routines__end(OUT);
}
#line 687 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
{
#line 706 "inform7/Chapter 21/Inform 6 Inclusions.w"
OUT = Code__Routines__begin(OUT, "PrintUseOption");
Code__LocalVariables__add_named_call("UO");
WRITE("switch(UO) {\n"); INDENT;
use_option *uo;
LOOP_OVER(uo, use_option) {
WRITE("%d: print \"", uo->allocation_id);
Text__print_raw_text_within_i6_literal(OUT, uo->word_ref1, uo->word_ref2);
WRITE(" option");
if (uo->minimum_setting_value > 0) WRITE(" [%d]", uo->minimum_setting_value);
WRITE("\";\n");
}
OUTDENT; WRITE("}\n");
OUT = Code__Routines__end(OUT);
}
#line 688 "inform7/Chapter 21/Inform 6 Inclusions.w"
;
}
#line 35 "inform7/Chapter 21/List Together.w"
void Code__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 21/List Together.w"
list_together_routine *latest_ltr_compiled = NULL;
int Code__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 21/List Together.w"
WRITE("Array LTR_%d --> CONSTANT_PACKED_TEXT_STORAGE LTR_%d_R;\n",
ltr->allocation_id, ltr->allocation_id);
OUT = Code__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 = Code__Routines__end(OUT);
}
#line 58 "inform7/Chapter 21/List Together.w"
;
latest_ltr_compiled = ltr;
N++;
}
return N;
}
#line 49 "inform7/Chapter 22/Construction Sequence.w"
int phrase_time_now = DAWN_PHT;
void 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 22/Construction Sequence.w"
void Code__Phrases__traverse_for_names(void) {
advance_phrase_time_to(EARLY_MORNING_PHT);
parse_node *p;
TREE_LOOP(p)
if (Parser__Nodes__type(p) == ROUTINE_NT)
Code__Phrases__Usage__predeclare_name_in(p);
}
#line 98 "inform7/Chapter 22/Construction Sequence.w"
sentence_handler COMMAND_SH_handler = { COMMAND_NT, -1, 0, NULL };
sentence_handler ROUTINE_SH_handler = { ROUTINE_NT, -1, 0, NULL };
#line 145 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__traverse(void) {
advance_phrase_time_to(LATE_MORNING_PHT);
parse_node *p;
int progress_target = 0;
TREE_LOOP(p) progress_target++;
int progress_made = 0;
TREE_LOOP(p) {
progress_made++;
if (progress_made % 10 == 0)
Problems__Progress__update_progress_bar(3,
((float) progress_made)/((float) progress_target));
if (Parser__Nodes__type(p) == ROUTINE_NT) {
Code__Phrases__create_from_preamble(p);
Parser__SP__MeaningLists__finish_this_session();
}
}
}
#line 176 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__register_meanings(void) {
advance_phrase_time_to(PRE_NOON_PHT);
Code__Routines__ToPhrases__register_all();
}
#line 209 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__parse_rule_parameters(void) {
advance_phrase_time_to(EARLY_AFTERNOON_PHT);
phrase *ph;
LOOP_OVER(ph, phrase) {
current_sentence = ph->declaration_node;
Code__Frames__make_current(&(ph->stack_frame));
ph->runtime_context_data =
Code__Phrases__Usage__to_runtime_context_data(&(ph->usage_data));
Code__Frames__remove_current();
Parser__SP__MeaningLists__finish_this_session();
}
}
#line 228 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__add_rules_to_rulebooks(void) {
advance_phrase_time_to(EARLY_AFTERNOON_PHT);
Code__Rules__Bookings__make_automatic_placements();
}
#line 243 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__parse_rule_placements(void) {
advance_phrase_time_to(EARLY_AFTERNOON_PHT);
parse_node *p;
TREE_LOOP(p)
if ((Parser__Nodes__type(p) == SENTENCE_NT) &&
(p->down) &&
(Parser__Nodes__type(p->down) == VERB_NT)) {
prevailing_mood =
Parser__Nodes__int_annotation(p->down, verbal_certainty_ANNOT);
int verb = Parser__Nodes__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:
Code__Rules__manual_placement(verb, p->down->next);
Parser__Nodes__annotate_int(p, sentence_unparsed_ANNOT, TRUE);
break;
}
}
}
#line 278 "inform7/Chapter 22/Construction Sequence.w"
int total_phrases_to_compile = 0;
int total_phrases_compiled = 0;
void Code__Phrases__compile_first_block(OUTPUT_STREAM) {
advance_phrase_time_to(MID_AFTERNOON_PHT);
{
#line 295 "inform7/Chapter 22/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 283 "inform7/Chapter 22/Construction Sequence.w"
;
{
#line 304 "inform7/Chapter 22/Construction Sequence.w"
WRITE("! Definitions of rules in rulebooks\n\n");
rulebook *rb;
LOOP_OVER(rb, rulebook)
Code__Rulebooks__compile_rule_phrases(rb, OUT,
&total_phrases_compiled, total_phrases_to_compile);
}
#line 284 "inform7/Chapter 22/Construction Sequence.w"
;
{
#line 313 "inform7/Chapter 22/Construction Sequence.w"
rule *R;
WRITE("! Definitions of displaced and unbooked rules\n\n");
LOOP_OVER(R, rule)
Code__Rules__compile_definition(OUT, R,
&total_phrases_compiled, total_phrases_to_compile);
}
#line 285 "inform7/Chapter 22/Construction Sequence.w"
;
{
#line 324 "inform7/Chapter 22/Construction Sequence.w"
WRITE("! Definitions of adjectives\n\n");
phrase *ph;
LOOP_OVER(ph, phrase)
if (Code__Phrases__Usage__get_effect(&(ph->usage_data)) ==
DEFINITIONAL_PHRASE_EFF)
Code__Phrases__compile(OUT, ph,
&total_phrases_compiled, total_phrases_to_compile, NULL, NULL, NULL);
Semantics__Adjectives__Phrases__compile_support_code(OUT);
}
#line 286 "inform7/Chapter 22/Construction Sequence.w"
;
{
#line 346 "inform7/Chapter 22/Construction Sequence.w"
phrase *ph;
LOOP_OVER(ph, phrase) {
kind *K = Code__Phrases__TypeData__kind(&(ph->type_data));
if (Kinds__definite(K)) {
if (ph->at_least_one_compiled_form_needed)
Code__Routines__ToPhrases__Requests__make(ph, K, NULL, -1, -1);
}
}
}
#line 287 "inform7/Chapter 22/Construction Sequence.w"
;
{
#line 358 "inform7/Chapter 22/Construction Sequence.w"
phrase *ph;
LOOP_OVER(ph, phrase) {
kind *KR = Code__Phrases__TypeData__get_return_kind(&(ph->type_data));
if ((Kinds__semidefinite(KR) == FALSE) &&
(Code__Phrases__TypeData__arithmetic_operation(ph) == -1)) {
current_sentence = Code__Phrases__declaration_node(ph);
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C22ReturnKindVague));
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__involves_var(KR, k)) &&
(Code__Phrases__TypeData__tokens_contain_variable(&(ph->type_data), k) == FALSE)) {
current_sentence = Code__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__handmade_problem(_P_(C22ReturnKindUndetermined));
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 288 "inform7/Chapter 22/Construction Sequence.w"
;
{
#line 395 "inform7/Chapter 22/Construction Sequence.w"
phrase *ph;
LOOP_OVER(ph, phrase)
if ((Code__Phrases__TypeData__invoked_inline(ph)) &&
(Code__Phrases__Usage__has_name_as_constant(&(ph->usage_data)))) {
current_sentence = Code__Phrases__declaration_node(ph);
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C22NamedInline));
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 289 "inform7/Chapter 22/Construction Sequence.w"
;
}
#line 421 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__TimedEventsTable_array(OUTPUT_STREAM) {
advance_phrase_time_to(LATE_AFTERNOON_PHT);
Code__Phrases__Timed__TimedEventsTable_array(OUT);
}
void Code__Phrases__TimedEventTimesTable_array(OUTPUT_STREAM) {
advance_phrase_time_to(LATE_AFTERNOON_PHT);
Code__Phrases__Timed__TimedEventTimesTable_array(OUT);
}
#line 434 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__rulebooks_array_array(OUTPUT_STREAM) {
advance_phrase_time_to(LATE_AFTERNOON_PHT);
Code__Rulebooks__rulebooks_array_array(OUT);
}
void Code__Phrases__compile_rulebooks(OUTPUT_STREAM) {
advance_phrase_time_to(LATE_AFTERNOON_PHT);
Code__Rulebooks__compile_rulebooks(OUT);
}
void Code__Phrases__RulebookNames_array(OUTPUT_STREAM) {
advance_phrase_time_to(LATE_AFTERNOON_PHT);
Code__Rulebooks__RulebookNames_array(OUT);
}
#line 455 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__compile_rule_printing_switch(OUTPUT_STREAM) {
advance_phrase_time_to(LATE_AFTERNOON_PHT);
Code__Rules__compile_rule_printing_switch(OUT);
}
#line 494 "inform7/Chapter 22/Construction Sequence.w"
void Code__Phrases__compile_as_needed(OUTPUT_STREAM) {
advance_phrase_time_to(EVENING_PHT);
int repeat = TRUE;
while (repeat) {
repeat = FALSE;
if (Code__Routines__ToPhrases__compilation_coroutine(OUT,
&total_phrases_compiled, total_phrases_to_compile) > 0)
repeat = TRUE;
if (Code__ListTogether__compilation_coroutine(OUT) > 0)
repeat = TRUE;
if (Plugins__Actions__ScopeLoops__compilation_coroutine(OUT) > 0)
repeat = TRUE;
if (Data__Strings__compilation_coroutine(OUT, FALSE) > 0)
repeat = TRUE;
if (Calculus__Propositions__compilation_coroutine(OUT) > 0)
repeat = TRUE;
}
}
#line 105 "inform7/Chapter 22/Phrases.w"
void Code__Phrases__create_from_preamble(parse_node *p) {
if ((p == NULL) || (Parser__Nodes__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 = UNKNOWN; /* and its manner of return */
int ow1 = -1, ow2 = -1; /* the text of the phrase options, if any */
int documentation_wn = -1; /* the documentation reference, if any */
{
#line 142 "inform7/Chapter 22/Phrases.w"
if ((p->down) && (p->down->next == NULL))
parse_possible_inline_defn(
p->down->word_ref1, p->down->word_ref2, &inline_wn, &mor);
if (inline_wn >= 0) {
char *inline_defn = Text__word_text(inline_wn);
if (Platform__strlen(inline_defn) >= MAX_INLINE_DEFN_LENGTH)
{
#line 283 "inform7/Chapter 22/Phrases.w"
LOG("Inline definition: <%s>\n", inline_defn);
Problems__sentence_problem(_P_(C22InlineTooLong),
"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 148 "inform7/Chapter 22/Phrases.w"
;
}
}
#line 113 "inform7/Chapter 22/Phrases.w"
;
ph_options_data phod;
ph_type_data phtd;
ph_usage_data phud;
ph_stack_frame phsf;
ph_runtime_context_data phrcd;
{
#line 154 "inform7/Chapter 22/Phrases.w"
phud = Code__Phrases__Usage__new(p->word_ref1, p->word_ref2, FALSE);
}
#line 121 "inform7/Chapter 22/Phrases.w"
;
int effect = Code__Phrases__Usage__get_effect(&phud);
if ((inline_wn >= 0) && (effect != TO_PHRASE_EFF))
{
#line 294 "inform7/Chapter 22/Phrases.w"
Problems__sentence_problem(_P_(C22InlineRule),
"only 'to...' phrases can be given inline Inform 6 definitions",
"and in particular rules and adjective definitions can't.");
}
#line 124 "inform7/Chapter 22/Phrases.w"
;
if ((effect != DEFINITIONAL_PHRASE_EFF) && (p->down == NULL))
{
#line 276 "inform7/Chapter 22/Phrases.w"
Problems__sentence_problem(_P_(C22Undefined),
"there doesn't seem to be any definition here",
"so I can't see what this rule or phrase would do.");
}
#line 127 "inform7/Chapter 22/Phrases.w"
;
{
#line 159 "inform7/Chapter 22/Phrases.w"
int x1 = -1, x2 = -1;
Code__Phrases__Usage__get_preamble_text(&phud, &x1, &x2);
phtd = Code__Phrases__TypeData__new();
if (inline_wn >= 0) Code__Phrases__TypeData__make_inline(&phtd);
switch (effect) {
case TO_PHRASE_EFF:
documentation_wn = Index__DocReferences__position_of_symbol(&x1, &x2);
Code__Phrases__TypeData__parse(&phtd, x1, x2, &ow1, &ow2);
break;
case DEFINITIONAL_PHRASE_EFF:
Code__Phrases__TypeData__set_mor(&phtd, DECIDES_CONDITION_MOR, NULL);
break;
default:
Code__Phrases__TypeData__set_mor(&phtd, DECIDES_NOTHING_AND_RETURNS_MOR, NULL);
break;
}
}
#line 129 "inform7/Chapter 22/Phrases.w"
;
{
#line 179 "inform7/Chapter 22/Phrases.w"
phod = Code__Phrases__Options__parse_declared_options(ow1, ow2);
}
#line 130 "inform7/Chapter 22/Phrases.w"
;
{
#line 191 "inform7/Chapter 22/Phrases.w"
phsf = Code__Frames__new();
Code__Phrases__TypeData__into_stack_frame(&phsf, &phtd,
Code__Phrases__TypeData__kind(&phtd), TRUE);
if (Code__Phrases__Options__allows_options(&phod))
Code__Frames__options_parameter_is_needed(&phsf);
}
#line 131 "inform7/Chapter 22/Phrases.w"
;
{
#line 200 "inform7/Chapter 22/Phrases.w"
phrcd = Code__Phrases__Context__new();
}
#line 132 "inform7/Chapter 22/Phrases.w"
;
phrase *new_ph;
{
#line 244 "inform7/Chapter 22/Phrases.w"
int x1 = -1, x2 = -1;
Code__Phrases__Usage__get_preamble_text(&phud, &x1, &x2);
LOGIF(PHRASE_CREATIONS, "Creating phrase: <$W>\n$U", x1, x2, &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_wn = documentation_wn;
}
#line 135 "inform7/Chapter 22/Phrases.w"
;
{
#line 205 "inform7/Chapter 22/Phrases.w"
switch (effect) {
case TO_PHRASE_EFF:
Code__Routines__ToPhrases__new(new_ph);
break;
case DEFINITIONAL_PHRASE_EFF:
{
#line 236 "inform7/Chapter 22/Phrases.w"
int cw1 = -1, cw2 = -1;
kind *K = NULL;
Code__Phrases__Adjectives__define_by_phrase(p, new_ph, &cw1, &cw2, &K);
Code__LocalVariables__Pronoun__add(&(new_ph->stack_frame), cw1, cw2, K);
}
#line 210 "inform7/Chapter 22/Phrases.w"
;
break;
case RULE_IN_RULEBOOK_EFF:
Code__Rules__request_automatic_placement(
Code__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:
Code__Phrases__Usage__to_rule(&(new_ph->usage_data), new_ph);
new_ph->compile_with_run_time_debugging = TRUE;
break;
}
}
#line 136 "inform7/Chapter 22/Phrases.w"
;
}
#line 307 "inform7/Chapter 22/Phrases.w"
int inline_phrase_definition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = DECIDES_NOTHING_MOR; inlinecode_NTMV = inline_phrase_definition_NTM->range_result_w1[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = DECIDES_CONDITION_MOR; inlinecode_NTMV = inline_phrase_definition_NTM->range_result_w1[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = DECIDES_VALUE_MOR; inlinecode_NTMV = inline_phrase_definition_NTM->range_result_w1[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = UNKNOWN; inlinecode_NTMV = inline_phrase_definition_NTM->range_result_w1[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = UNKNOWN; inlinecode_NTMV = inline_phrase_definition_NTM->range_result_w1[1];
{
#line 317 "inform7/Chapter 22/Phrases.w"
*X = UNKNOWN;
Problems__sentence_problem(_P_(C22TailAfterInline),
"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 312 "inform7/Chapter 22/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 313 "inform7/Chapter 22/Phrases.w"
#line 326 "inform7/Chapter 22/Phrases.w"
void parse_possible_inline_defn(int w1, int w2, int *wn, int *mor) {
LOGIF(MATCHING, "form of inline: $W\n", w1, w2);
*wn = -1;
if (parse_nt_against_word_range(inline_phrase_definition_NTM, w1, w2, NULL, NULL)) { *wn = inlinecode_NTMV; *mor = most_recent_result; }
}
#line 336 "inform7/Chapter 22/Phrases.w"
void Code__Phrases__log(phrase *ph) {
if (ph == NULL) { LOG("RULE:NULL"); return; }
LOG("%s", ph->ph_I6_identifier);
Code__Phrases__Usage__log_rule_name(&(ph->usage_data));
}
void Code__Phrases__log_briefly(phrase *ph) {
Code__Phrases__TypeData__log_briefly(&(ph->type_data));
}
#line 349 "inform7/Chapter 22/Phrases.w"
void Code__Phrases__write_HTML_representation(OUTPUT_STREAM, phrase *ph, int format) {
Code__Phrases__TypeData__write_HTML_representation(OUT, &(ph->type_data), format, NULL);
}
#line 356 "inform7/Chapter 22/Phrases.w"
char *Code__Routines__ToPhrases__get_inline_definition(phrase *ph) {
if (ph->inline_wn < 0)
internal_error("tried to access inline definition of non-inline phrase");
return Text__word_text(ph->inline_wn);
}
char *Code__Phrases__identifier(phrase *ph) {
return ph->ph_I6_identifier;
}
parse_node *Code__Phrases__declaration_node(phrase *ph) {
return ph->declaration_node;
}
#line 377 "inform7/Chapter 22/Phrases.w"
void Code__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 = Code__Phrases__Usage__get_effect(&(ph->usage_data));
if (effect == TO_PHRASE_EFF) {
Code__Routines__compile(OUT, ph, legible, req, acl);
{
#line 395 "inform7/Chapter 22/Phrases.w"
if (ph->at_least_one_compiled_form_needed) {
ph->at_least_one_compiled_form_needed = FALSE;
(*i)++;
Problems__Progress__update_progress_bar(4, ((float) (*i))/((float) max_i));
}
}
#line 383 "inform7/Chapter 22/Phrases.w"
;
} else {
if (ph->at_least_one_compiled_form_needed) {
Code__Routines__compile(OUT, ph, legible, NULL, acl);
{
#line 395 "inform7/Chapter 22/Phrases.w"
if (ph->at_least_one_compiled_form_needed) {
ph->at_least_one_compiled_form_needed = FALSE;
(*i)++;
Problems__Progress__update_progress_bar(4, ((float) (*i))/((float) max_i));
}
}
#line 387 "inform7/Chapter 22/Phrases.w"
;
}
}
}
#line 49 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__predeclare_name_in(parse_node *p) {
ph_usage_data phud = Code__Phrases__Usage__new(p->word_ref1, p->word_ref2, TRUE);
if (phud.explicit_name_w1 >= 0)
Code__Rules__new(phud.explicit_name_w1, phud.explicit_name_w2, TRUE);
}
#line 70 "inform7/Chapter 22/Phrase Usage.w"
rule *Code__Phrases__Usage__to_rule(ph_usage_data *phud, phrase *ph) {
int rw1 = -1, rw2 = -1, explicitly = FALSE;
{
#line 88 "inform7/Chapter 22/Phrase Usage.w"
if (phud->event_name_w1 >= 0) {
rw1 = phud->event_name_w1; rw2 = phud->event_name_w2;
} else {
rw1 = phud->explicit_name_w1; rw2 = phud->explicit_name_w2;
if (rw1 >= 0) explicitly = TRUE;
}
if (rw1 >= 0) Text__Languages__remove_the(&rw1, &rw2);
}
#line 72 "inform7/Chapter 22/Phrase Usage.w"
;
rule *R = NULL;
if (rw1 >= 0) R = Code__Rules__by_name(rw1, rw2);
if (R)
{
#line 99 "inform7/Chapter 22/Phrase Usage.w"
phrase *ph_found = Code__Rules__get_I7_definition(R);
if ((ph_found) && (ph_found != ph)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, rw1, rw2);
Problems__handmade_problem(_P_(C22DuplicateRuleName));
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 76 "inform7/Chapter 22/Phrase Usage.w"
else R = Code__Rules__new(rw1, rw2, explicitly);
Code__Rules__set_I7_definition(R, ph);
{
#line 113 "inform7/Chapter 22/Phrase Usage.w"
int ix1 = phud->rule_parameter_w1, ix2 = phud->rule_parameter_w2;
if (phud->whenwhile_w1 >= 0) {
if (phud->whenwhile_w1 == phud->rule_parameter_w2 + 1) {
ix2 = phud->whenwhile_w2;
} else {
ix1 = phud->whenwhile_w1; ix2 = phud->whenwhile_w2;
}
}
Code__Rules__set_italicised_index_text(R, ix1, ix2);
}
#line 80 "inform7/Chapter 22/Phrase Usage.w"
;
return R;
}
#line 132 "inform7/Chapter 22/Phrase Usage.w"
int rule_preamble_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 152 "inform7/Chapter 22/Phrase Usage.w"
Problems__sentence_problem(_P_(C22NamelessRule),
"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 135 "inform7/Chapter 22/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 160 "inform7/Chapter 22/Phrase Usage.w"
Problems__sentence_problem(_P_(C22UnarticledRule),
"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 136 "inform7/Chapter 22/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *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 5:
{
#line 169 "inform7/Chapter 22/Phrase Usage.w"
Problems__sentence_problem(_P_(C22BareTo),
"'to' what? No name is given",
"which means that this would not define a new phrase.");
}
#line 138 "inform7/Chapter 22/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 176 "inform7/Chapter 22/Phrase Usage.w"
Problems__sentence_problem(_P_(C22DontCallPhrasesWithCalled),
"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 139 "inform7/Chapter 22/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *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 8: *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 9: *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 10: *X = TO_PHRASE_EFF; named_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11: *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 12:
{
#line 152 "inform7/Chapter 22/Phrase Usage.w"
Problems__sentence_problem(_P_(C22NamelessRule),
"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 145 "inform7/Chapter 22/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13:
{
#line 160 "inform7/Chapter 22/Phrase Usage.w"
Problems__sentence_problem(_P_(C22UnarticledRule),
"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 146 "inform7/Chapter 22/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14: *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 148 "inform7/Chapter 22/Phrase Usage.w"
#line 186 "inform7/Chapter 22/Phrase Usage.w"
int now_phrase_preamble_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 188 "inform7/Chapter 22/Phrase Usage.w"
#line 196 "inform7/Chapter 22/Phrase Usage.w"
int rule_preamble_fine_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = R[1]; specification_scenes_NTMV = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; specification_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 199 "inform7/Chapter 22/Phrase Usage.w"
int rule_preamble_finer_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 204 "inform7/Chapter 22/Phrase Usage.w"
int rulebook_stem_embellished_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; bud1_NTMV = rulebook_stem_embellished_NTM->range_result_w1[1]; bud2_NTMV = rulebook_stem_embellished_NTM->range_result_w2[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; bud1_NTMV = rulebook_stem_embellished_NTM->range_result_w1[1]; bud2_NTMV = rulebook_stem_embellished_NTM->range_result_w2[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; bud1_NTMV = -1; bud2_NTMV = -1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; bud1_NTMV = rulebook_stem_embellished_NTM->range_result_w1[1]; bud2_NTMV = rulebook_stem_embellished_NTM->range_result_w2[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 0; bud1_NTMV = rulebook_stem_embellished_NTM->range_result_w1[1]; bud2_NTMV = rulebook_stem_embellished_NTM->range_result_w2[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = 0; bud1_NTMV = rulebook_stem_embellished_NTM->range_result_w1[1]; bud2_NTMV = rulebook_stem_embellished_NTM->range_result_w2[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = 0; bud1_NTMV = rulebook_stem_embellished_NTM->range_result_w1[1]; bud2_NTMV = rulebook_stem_embellished_NTM->range_result_w2[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = 0; bud1_NTMV = rulebook_stem_embellished_NTM->range_result_w1[1]; bud2_NTMV = rulebook_stem_embellished_NTM->range_result_w2[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 214 "inform7/Chapter 22/Phrase Usage.w"
#line 218 "inform7/Chapter 22/Phrase Usage.w"
rulebook_match parsed_rm;
#line 233 "inform7/Chapter 22/Phrase Usage.w"
int no_now_phrases = 0;
ph_usage_data Code__Phrases__Usage__new(int w1, int w2, int coarse_mode) {
ph_usage_data phud;
{
#line 262 "inform7/Chapter 22/Phrase Usage.w"
phud.full_preamble_w1 = w1; phud.full_preamble_w2 = w2;
phud.constant_phrase_holder = NULL;
phud.phrase_effect = AS_YET_UNKNOWN_EFF;
phud.explicit_name_w1 = -1; phud.explicit_name_w2 = -1;
phud.explicit_name_used_in_maths = FALSE;
phud.rule_preamble_w1 = -1; phud.rule_preamble_w2 = -1;
phud.rule_parameter_w1 = -1; phud.rule_parameter_w2 = -1;
phud.whenwhile_w1 = -1; phud.whenwhile_w2 = -1;
phud.during_scene_spec = NULL;
phud.event_name_w1 = -1; phud.event_name_w2 = -1;
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 = -1;
}
#line 237 "inform7/Chapter 22/Phrase Usage.w"
;
if (parse_nt_against_word_range(rule_preamble_NTM, w1, w2, NULL, NULL)) {
phud.phrase_effect = most_recent_result;
switch (most_recent_result) {
case TO_PHRASE_EFF:
{
#line 281 "inform7/Chapter 22/Phrase Usage.w"
phud.rule_preamble_w1 = w1;
phud.rule_preamble_w2 = w2;
if (named_NTMV)
{
#line 301 "inform7/Chapter 22/Phrase Usage.w"
int n1 = -1, n2 = -1, r1 = -1, r2 = -1;
GET_RW(rule_preamble_NTM, 1, r1, r2);
GET_RW(rule_preamble_NTM, 2, n1, n2);
if (coarse_mode) {
if (parse_nt_against_word_range(spec_type_expression_NTM, n1, n2, NULL, NULL)) {
Problems__sentence_problem(_P_(C22PhraseNameDuplicated),
"that name for this new phrase is not allowed",
"because it already has a meaning.");
}
phud.constant_phrase_holder = Code__Phrases__Constants__parse(n1, n2);
if (phud.constant_phrase_holder == NULL)
phud.constant_phrase_holder =
Code__Phrases__Constants__create(n1, n2, r1, r2);
} else {
constant_phrase *cphr = Code__Phrases__Constants__parse(n1, n2);
if (Kinds__definite(cphr->cphr_kind) == FALSE) {
phrase *ph = Code__Phrases__Constants__as_phrase(cphr);
if (ph) current_sentence = Code__Phrases__declaration_node(ph);
Problems__quote_source(1,
Parser__Sentences__NPs__new_raw(cphr->word_ref1, cphr->word_ref2));
Problems__quote_words(2, cphr->word_ref1, cphr->word_ref2);
Problems__handmade_problem(_P_(C22NamedGeneric));
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) {
int inv_wn = -1;
GET_RW(rule_preamble_NTM, 3, inv_wn, inv_wn);
phud.explicit_name_for_inverse = inv_wn;
}
}
phud.constant_phrase_holder = cphr;
}
phud.rule_preamble_w1 = r1;
phud.rule_preamble_w2 = r2;
}
#line 284 "inform7/Chapter 22/Phrase Usage.w"
;
if (parse_nt_against_word_range(now_phrase_preamble_NTM, w1, w2, NULL, NULL)) {
if ((coarse_mode) && (no_now_phrases++ == 1)) {
Problems__sentence_problem(_P_(C22RedefinedNow),
"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 243 "inform7/Chapter 22/Phrase Usage.w"
;
break;
case DEFINITIONAL_PHRASE_EFF:
break;
case RULE_IN_RULEBOOK_EFF:
{
#line 349 "inform7/Chapter 22/Phrase Usage.w"
if (named_NTMV) {
GET_RW(rule_preamble_NTM, 1, w1, w2);
GET_RW(rule_preamble_NTM, 2, (phud.explicit_name_w1), (phud.explicit_name_w2));
}
if (coarse_mode == FALSE)
{
#line 375 "inform7/Chapter 22/Phrase Usage.w"
parse_nt_against_word_range(rule_preamble_fine_NTM, w1, w2, NULL, NULL);
GET_RW(rule_preamble_finer_NTM, 1, w1, w2);
if (most_recent_result == NOT_APPLICABLE) {
parse_nt_against_word_range(unrecognised_rule_stem_diagnosis_NTM, w1, w2, NULL, NULL);
} else {
if (most_recent_result)
GET_RW(rule_preamble_finer_NTM, 2, (phud.whenwhile_w1), (phud.whenwhile_w2));
phud.during_scene_spec = specification_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 465 "inform7/Chapter 22/Phrase Usage.w"
if ((parsed_rm.article_used == DEF_ART) &&
(parsed_rm.placement_requested == MIDDLE_PLACEMENT))
Problems__sentence_problem(_P_(C22RuleWithDefiniteArticle),
"a rulebook can contain any number of rules",
"so (e.g.) 'the before rule: ...' is disallowed; you should "
"write 'a before rule: ...' instead.");
}
#line 386 "inform7/Chapter 22/Phrase Usage.w"
;
{
#line 396 "inform7/Chapter 22/Phrase Usage.w"
if (bud1_NTMV == -1) {
bud1_NTMV = parsed_rm.match_from + parsed_rm.advance_words;
bud2_NTMV = parsed_rm.match_from + parsed_rm.advance_words - 1;
}
if (parsed_rm.advance_words != parsed_rm.match_length)
bud1_NTMV = parsed_rm.match_from + parsed_rm.match_length;
bud2_NTMV -= parsed_rm.tail_words;
if (bud1_NTMV <= bud2_NTMV) {
phud.rule_parameter_w1 = bud1_NTMV;
phud.rule_parameter_w2 = bud2_NTMV;
}
if ((phud.owning_rulebook) &&
(Code__Rulebooks__runs_during_activities(phud.owning_rulebook) == FALSE) &&
(Code__Rulebooks__focus(phud.owning_rulebook) == ACTION_FOCUS) &&
(phud.rule_parameter_w1 >= 0) &&
(phud.whenwhile_w1 >= 0)) {
phud.rule_parameter_w2 = phud.whenwhile_w2;
phud.whenwhile_w1 = -1;
phud.whenwhile_w2 = -1;
}
}
#line 387 "inform7/Chapter 22/Phrase Usage.w"
;
}
phud.rule_preamble_w1 = w1;
phud.rule_preamble_w2 = w2;
}
#line 353 "inform7/Chapter 22/Phrase Usage.w"
;
}
#line 248 "inform7/Chapter 22/Phrase Usage.w"
;
break;
case RULE_NOT_IN_RULEBOOK_EFF:
{
#line 358 "inform7/Chapter 22/Phrase Usage.w"
if (event_time_NTMV == NOT_AN_EVENT) {
GET_RW(rule_preamble_NTM, 1, (phud.explicit_name_w1), (phud.explicit_name_w2));
Code__Rules__vet_name(phud.explicit_name_w1, phud.explicit_name_w2);
} else {
phud.timing_of_event = event_time_NTMV;
if (event_time_NTMV == NO_FIXED_TIME)
GET_RW(event_rule_preamble_NTM, 1, (phud.event_name_w1), (phud.event_name_w2));
}
}
#line 251 "inform7/Chapter 22/Phrase Usage.w"
;
break;
}
}
return phud;
}
#line 420 "inform7/Chapter 22/Phrase Usage.w"
int unrecognised_rule_stem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 427 "inform7/Chapter 22/Phrase Usage.w"
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C22BadRulePreambleWhen));
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 421 "inform7/Chapter 22/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 452 "inform7/Chapter 22/Phrase Usage.w"
Problems__sentence_problem(_P_(C22BadRulePreamble),
"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 422 "inform7/Chapter 22/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 423 "inform7/Chapter 22/Phrase Usage.w"
#line 476 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__get_preamble_text(ph_usage_data *phud, int *w1, int *w2) {
if (phud->phrase_effect == TO_PHRASE_EFF) {
*w1 = phud->rule_preamble_w1; *w2 = phud->rule_preamble_w2;
} else {
*w1 = phud->full_preamble_w1; *w2 = phud->full_preamble_w2;
}
}
#line 491 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__get_prewhile_text(ph_usage_data *phud, int *pw1, int *pw2) {
int w1 = phud->rule_parameter_w1, w2 = phud->rule_parameter_w2;
if (w1 >= 0) {
int e1 = w1, e2 = w2, x1, x2;
if (parse_nt_against_word_range(when_while_clause_NTM, e1, e2, NULL, NULL)) {
GET_RW(when_while_clause_NTM, 1, e1, e2);
GET_RW(when_while_clause_NTM, 2, x1, x2);
}
*pw1 = e1; *pw2 = e2;
} else {
*pw1 = -1; *pw2 = -1;
}
}
#line 508 "inform7/Chapter 22/Phrase Usage.w"
int when_while_clause_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 510 "inform7/Chapter 22/Phrase Usage.w"
#line 515 "inform7/Chapter 22/Phrase Usage.w"
int Code__Phrases__Usage__get_effect(ph_usage_data *phud) {
return phud->phrase_effect;
}
int Code__Phrases__Usage__get_rulebook_placement(ph_usage_data *phud) {
return phud->owning_rulebook_placement;
}
rulebook *Code__Phrases__Usage__get_rulebook(ph_usage_data *phud) {
return phud->owning_rulebook;
}
void Code__Phrases__Usage__set_rulebook(ph_usage_data *phud, rulebook *rb) {
phud->owning_rulebook = rb;
}
int Code__Phrases__Usage__get_timing_of_event(ph_usage_data *phud) {
return phud->timing_of_event;
}
int Code__Phrases__Usage__has_name_as_constant(ph_usage_data *phud) {
if ((phud->constant_phrase_holder) &&
(phud->explicit_name_used_in_maths == FALSE) &&
(phud->constant_phrase_holder->word_ref1 >= 0)) return TRUE;
return FALSE;
}
int Code__Phrases__Usage__get_equation_form(ph_usage_data *phud) {
if (phud->explicit_name_used_in_maths)
return phud->constant_phrase_holder->word_ref1;
return -1;
}
phrase *Code__Phrases__Usage__get_equation_inverse(ph_usage_data *phud) {
if (phud->explicit_name_for_inverse >= 0) {
phrase *ph;
LOOP_OVER(ph, phrase) {
int w = Code__Phrases__Usage__get_equation_form(&(ph->usage_data));
if (w >= 0)
if (compare_words(w, phud->explicit_name_for_inverse))
return ph;
}
}
return NULL;
}
#line 567 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__log(ph_usage_data *phud) {
char *ram = "<UNKNOWN>";
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_w1, phud->full_preamble_w2, ram);
if (phud->constant_phrase_holder)
LOG(" Constant name: <$W>\n",
phud->constant_phrase_holder->word_ref1, phud->constant_phrase_holder->word_ref2);
if (phud->explicit_name_w1 >= 0)
LOG(" Explicit name: <$W>\n",
phud->explicit_name_w1, phud->explicit_name_w2);
if (phud->explicit_name_used_in_maths)
LOG(" Used functionally in equations\n");
if (phud->rule_preamble_w1 >= 0)
LOG(" Rule preamble: <$W>\n",
phud->rule_preamble_w1, phud->rule_preamble_w2);
if (phud->rule_parameter_w1 >= 0)
LOG(" Rule parameter: <$W>\n",
phud->rule_parameter_w1, phud->rule_parameter_w2);
if (phud->whenwhile_w1 >= 0)
LOG(" When/while text: <$W>\n",
phud->whenwhile_w1, phud->whenwhile_w2);
if (phud->event_name_w1 >= 0)
LOG(" Event name: <$W>\n",
phud->event_name_w1, phud->event_name_w2);
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: <$S>\n", phud->during_scene_spec);
if (phud->owning_rulebook) {
char *place = "<UNKNOWN>";
LOG(" Owned by rulebook: ");
Code__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 Code__Phrases__Usage__log_rule_name(ph_usage_data *phud) {
if (phud->explicit_name_w1 < 0) {
if (phud->full_preamble_w1 >= 0)
LOG("\"$W\"", phud->full_preamble_w1, phud->full_preamble_w2);
else LOG("(nameless)");
} else LOG("($W)", phud->explicit_name_w1, phud->explicit_name_w2);
}
#line 626 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__write_I6_comment_describing(ph_usage_data *phud, OUTPUT_STREAM) {
WRITE("! ");
Text__print_raw_text_within_i6_literal(OUT, phud->full_preamble_w1, phud->full_preamble_w2);
WRITE(":\n");
}
#line 635 "inform7/Chapter 22/Phrase Usage.w"
void Code__Phrases__Usage__index_preamble(ph_usage_data *phud) {
Text__print_raw_text_to_stream(phud->full_preamble_w1, phud->full_preamble_w2, ifl);
}
#line 649 "inform7/Chapter 22/Phrase Usage.w"
int NAP_problem_explained = FALSE; /* pertains to Named Action Patterns */
int issuing_ANL_problem = FALSE; /* pertains to Action Name Lists */
#line 655 "inform7/Chapter 22/Phrase Usage.w"
ph_runtime_context_data Code__Phrases__Usage__to_runtime_context_data(ph_usage_data *phud) {
ph_runtime_context_data phrcd = Code__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 670 "inform7/Chapter 22/Phrase Usage.w"
phrcd.compile_for_rulebook = &(phud->owning_rulebook);
if (phud->rule_parameter_w1 >= 0)
{
#line 685 "inform7/Chapter 22/Phrase Usage.w"
int aw1 = phud->rule_parameter_w1, aw2 = phud->rule_parameter_w2;
if (Code__Rulebooks__focus(phud->owning_rulebook) == ACTION_FOCUS) {
permit_trying_omission = TRUE;
Code__Frames__set_stvol(
Code__Frames__current_stack_frame(), all_action_processing_vars);
if (parse_nt_against_word_range(action_pattern_NTM, aw1, aw2, NULL, NULL)) phrcd.ap = *((action_pattern *) most_recent_result_p);
Code__Frames__remove_nonphrase_stack_frame();
permit_trying_omission = FALSE;
if (Plugins__Actions__Patterns__is_valid(&(phrcd.ap)) == FALSE)
{
#line 723 "inform7/Chapter 22/Phrase Usage.w"
Code__Phrases__Usage__log(phud);
LOG("Bad action pattern: $W = $A\nPAP failure reason: %d\n",
aw1, aw2, &(phrcd.ap), pap_failure_reason);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, aw1, aw2);
if (parse_nt_against_word_range(action_problem_diagnosis_NTM, aw1, aw2, NULL, NULL) == FALSE)
switch(pap_failure_reason) {
case MIXEDNOUNS_PAPF:
{
#line 740 "inform7/Chapter 22/Phrase Usage.w"
Problems__handmade_problem(_P_(C22APWithDisjunction));
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 730 "inform7/Chapter 22/Phrase Usage.w"
; break;
case NOPARTICIPLE_PAPF:
{
#line 757 "inform7/Chapter 22/Phrase Usage.w"
Problems__handmade_problem(_P_(C22APWithNoParticiple));
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 731 "inform7/Chapter 22/Phrase Usage.w"
; break;
case IMMISCIBLE_PAPF:
{
#line 769 "inform7/Chapter 22/Phrase Usage.w"
Problems__handmade_problem(_P_(C22APWithImmiscible));
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 732 "inform7/Chapter 22/Phrase Usage.w"
; break;
case WHEN_PAPF:
{
#line 784 "inform7/Chapter 22/Phrase Usage.w"
Problems__handmade_problem(_P_(C22APWithBadWhen));
int qw1 = aw1, qw2 = aw2, diagnosis = 0;
if (parse_nt_against_word_range(action_when_diagnosis_NTM, qw1, qw2, NULL, NULL)) {
qw1 = cw1_NTMV; qw2 = cw2_NTMV;
diagnosis = most_recent_result;
}
Problems__quote_words(2, qw1, qw2);
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 733 "inform7/Chapter 22/Phrase Usage.w"
; break;
default:
{
#line 820 "inform7/Chapter 22/Phrase Usage.w"
Problems__quote_words(2, aw1, aw2);
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__handmade_problem(_P_(C22APUnknown));
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 838 "inform7/Chapter 22/Phrase Usage.w"
action_name *an;
LOOP_OVER(an, action_name) {
int x1 = an->word_ref1, x2 = an->word_ref2;
if (aw2-aw1 < x2-x1) {
if (Text__compare_word_range(aw1, aw2, x1, x1 + aw2 - aw1)) {
Problems__quote_words(3, x1, x2);
Problems__issue_problem_segment(
" I notice that there's an action called '%3', though: perhaps "
"this is what you meant?");
break;
}
}
}
}
#line 829 "inform7/Chapter 22/Phrase Usage.w"
;
{
#line 862 "inform7/Chapter 22/Phrase Usage.w"
issuing_ANL_problem = FALSE; NAP_problem_explained = FALSE;
parse_nt_against_word_range(anl_diagnosis_NTM, aw1, aw2, NULL, NULL);
int N = most_recent_result;
if (N > 1) {
int avoids = FALSE;
if ((parse_nt_against_word_range(action_list_NTM, aw1, aw2, 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;
parse_nt_against_word_range(anl_diagnosis_NTM, aw1, aw2, NULL, NULL);
Problems__issue_problem_segment(" so");
}
}
#line 830 "inform7/Chapter 22/Phrase Usage.w"
;
Problems__issue_problem_segment(
" I am unable to place this rule into any rulebook.");
Problems__issue_problem_end();
}
#line 734 "inform7/Chapter 22/Phrase Usage.w"
; break;
}
}
#line 696 "inform7/Chapter 22/Phrase Usage.w"
;
} else {
kind *pk = Code__Rulebooks__get_parameter_kind(phud->owning_rulebook);
phrcd.ap = Plugins__Actions__Patterns__parse_parametric(aw1, aw2, pk);
if (Plugins__Actions__Patterns__is_valid(&(phrcd.ap)) == FALSE) {
if (phud->whenwhile_w1 >= 0) {
phrcd.ap = Plugins__Actions__Patterns__parse_parametric(
aw1, phud->whenwhile_w2, pk);
if (Plugins__Actions__Patterns__is_valid(&(phrcd.ap)) == TRUE) {
phud->rule_parameter_w2 = phud->whenwhile_w2;
phud->whenwhile_w1 = -1; phud->whenwhile_w2 = -1;
}
}
}
if (Plugins__Actions__Patterns__is_valid(&(phrcd.ap)) == FALSE)
{
#line 883 "inform7/Chapter 22/Phrase Usage.w"
Code__Phrases__Usage__log(phud);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, aw1, aw2);
Problems__quote_kind(3, pk);
int rp1 = phud->rule_preamble_w1, rp2 = phud->rule_preamble_w2;
parse_nt_against_word_range(parametric_problem_diagnosis_NTM, rp1, rp2, NULL, NULL);
}
#line 711 "inform7/Chapter 22/Phrase Usage.w"
;
}
}
#line 672 "inform7/Chapter 22/Phrase Usage.w"
;
if (phud->whenwhile_w1 >= 0) {
phrcd.activity_context_w1 = phud->whenwhile_w1+1;
phrcd.activity_context_w2 = phud->whenwhile_w2;
phrcd.activity_where = current_sentence;
}
if (phud->during_scene_spec) phrcd.during_scene = phud->during_scene_spec;
}
#line 662 "inform7/Chapter 22/Phrase Usage.w"
;
return phrcd;
}
#line 897 "inform7/Chapter 22/Phrase Usage.w"
int parametric_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 904 "inform7/Chapter 22/Phrase Usage.w"
Problems__sentence_problem(_P_(C22WhenThePlay),
"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 898 "inform7/Chapter 22/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 913 "inform7/Chapter 22/Phrase Usage.w"
Problems__handmade_problem(_P_(C22BadParameter));
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 899 "inform7/Chapter 22/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 900 "inform7/Chapter 22/Phrase Usage.w"
#line 924 "inform7/Chapter 22/Phrase Usage.w"
int action_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 931 "inform7/Chapter 22/Phrase Usage.w"
Problems__handmade_problem(_P_(C22NonActionInPresenceOf));
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 925 "inform7/Chapter 22/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 947 "inform7/Chapter 22/Phrase Usage.w"
Problems__handmade_problem(_P_(C22NonActionIn));
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 926 "inform7/Chapter 22/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 927 "inform7/Chapter 22/Phrase Usage.w"
#line 962 "inform7/Chapter 22/Phrase Usage.w"
int action_when_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 1; cw1_NTMV = action_when_diagnosis_NTM->range_result_w1[2]; cw2_NTMV = action_when_diagnosis_NTM->range_result_w2[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2; cw1_NTMV = action_when_diagnosis_NTM->range_result_w1[2]; cw2_NTMV = action_when_diagnosis_NTM->range_result_w2[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 3; cw1_NTMV = action_when_diagnosis_NTM->range_result_w1[2]; cw2_NTMV = action_when_diagnosis_NTM->range_result_w2[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 4; cw1_NTMV = action_when_diagnosis_NTM->range_result_w1[2]; cw2_NTMV = action_when_diagnosis_NTM->range_result_w2[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 5; cw1_NTMV = action_when_diagnosis_NTM->range_result_w1[2]; cw2_NTMV = action_when_diagnosis_NTM->range_result_w2[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 968 "inform7/Chapter 22/Phrase Usage.w"
#line 972 "inform7/Chapter 22/Phrase Usage.w"
int anl_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 975 "inform7/Chapter 22/Phrase Usage.w"
int anl_inner_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 979 "inform7/Chapter 22/Phrase Usage.w"
int anl_tail_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 983 "inform7/Chapter 22/Phrase Usage.w"
int anl_entry_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 990 "inform7/Chapter 22/Phrase Usage.w"
*X = 1;
if ((issuing_ANL_problem) && (!preform_lookahead_mode)) {
Problems__quote_words(4, w1, w2);
if (parse_nt_against_word_range(action_pattern_NTM, w1, w2, 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 (Plugins__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 (Plugins__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 (parse_nt_against_word_range(named_action_pattern_NTM, w1, w2, 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 985 "inform7/Chapter 22/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 986 "inform7/Chapter 22/Phrase Usage.w"
#line 47 "inform7/Chapter 22/Phrase Runtime Context Data.w"
ph_runtime_context_data Code__Phrases__Context__new(void) {
ph_runtime_context_data phrcd;
phrcd.activity_context_w1 = -1; phrcd.activity_context_w2 = -1;
phrcd.activity_where = NULL;
phrcd.avl = NULL;
phrcd.during_scene = NULL;
phrcd.ap = Plugins__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 66 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__set_always_test_actor(ph_runtime_context_data *phrcd) {
phrcd->always_test_actor = TRUE;
}
void Code__Phrases__Context__clear_always_test_actor(ph_runtime_context_data *phrcd) {
phrcd->always_test_actor = FALSE;
}
void Code__Phrases__Context__set_never_test_actor(ph_runtime_context_data *phrcd) {
phrcd->never_test_actor = TRUE;
}
void Code__Phrases__Context__set_marked_for_anyone(ph_runtime_context_data *phrcd, int to) {
phrcd->marked_for_anyone = to;
}
int Code__Phrases__Context__get_marked_for_anyone(ph_runtime_context_data *phrcd) {
return phrcd->marked_for_anyone;
}
#line 89 "inform7/Chapter 22/Phrase Runtime Context Data.w"
int Code__Phrases__Context__within_action_context(ph_runtime_context_data *phrcd,
action_name *an) {
if (phrcd == NULL) return FALSE;
return Plugins__Actions__Patterns__within_action_context(&(phrcd->ap), an);
}
action_name *Code__Phrases__Context__required_action(ph_runtime_context_data *phrcd) {
if (Plugins__Actions__Patterns__is_valid(&(phrcd->ap)))
return Plugins__Actions__Patterns__required_action(&(phrcd->ap));
return NULL;
}
void Code__Phrases__Context__suppress_action_testing(ph_runtime_context_data *phrcd) {
Plugins__Actions__Patterns__suppress_action_testing(&(phrcd->ap));
}
#line 111 "inform7/Chapter 22/Phrase Runtime Context Data.w"
scene *Code__Phrases__Context__get_scene(ph_runtime_context_data *phrcd) {
if (phrcd == NULL) return NULL;
if (Specifications__family_is(phrcd->during_scene, VALUE_FMY)) {
instance *q = Specifications__Values__get_named_constant_if_any(phrcd->during_scene);
if (q) return Plugins__Scenes__from_named_constant(q);
}
return NULL;
}
#line 124 "inform7/Chapter 22/Phrase Runtime Context Data.w"
int Code__Phrases__Context__outcome_restrictions_waived(void) {
if ((phrase_being_compiled) &&
(phrase_being_compiled->runtime_context_data.permit_all_outcomes))
return TRUE;
return FALSE;
}
#line 142 "inform7/Chapter 22/Phrase Runtime Context Data.w"
int Code__Phrases__Context__compare_specificity(ph_runtime_context_data *rcd1,
ph_runtime_context_data *rcd2) {
action_pattern *ap1, *ap2;
specification *sc1, *sc2;
int al1_w1, al1_w2, al2_w1, al2_w2;
{
#line 159 "inform7/Chapter 22/Phrase Runtime Context Data.w"
if (rcd1) {
ap1 = &(rcd1->ap); sc1 = rcd1->during_scene;
al1_w1 = rcd1->activity_context_w1; al1_w2 = rcd1->activity_context_w2;
} else {
ap1 = NULL; sc1 = NULL; al1_w1 = -1; al1_w2 = -1;
}
if (rcd2) {
ap2 = &(rcd2->ap); sc2 = rcd2->during_scene;
al2_w1 = rcd2->activity_context_w1; al2_w2 = rcd2->activity_context_w2;
} else {
ap2 = NULL; sc2 = NULL; al2_w1 = -1; al2_w2 = -1;
}
}
#line 147 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
{
#line 175 "inform7/Chapter 22/Phrase Runtime Context Data.w"
c_s_stage_law = "I - Number of aspects constrained";
int rct1 = Plugins__Actions__Patterns__count_aspects(ap1);
int rct2 = Plugins__Actions__Patterns__count_aspects(ap2);
if (al1_w1 >= 0) rct1++; if (al2_w1 >= 0) rct2++;
if (sc1) rct1++; if (sc2) rct2++;
if (rct1 > rct2) return 1;
if (rct1 < rct2) return -1;
}
#line 148 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
{
#line 188 "inform7/Chapter 22/Phrase Runtime Context Data.w"
if ((sc1) && (sc2)) {
int rv = Specifications__compare_specificity(sc1, sc2, NULL);
if (rv != 0) return rv;
}
}
#line 149 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
{
#line 196 "inform7/Chapter 22/Phrase Runtime Context Data.w"
c_s_stage_law = "III - When/while requirement";
if ((al1_w1 >= 0) && (al2_w1 == -1)) return 1;
if ((al1_w1 == -1) && (al2_w1 >= 0)) return -1;
if (al1_w1 >= 0) {
int n1 = Code__Activities__Lists__count(rcd1->avl);
int n2 = Code__Activities__Lists__count(rcd2->avl);
if (n1 > n2) return 1;
if (n2 > n1) return -1;
}
}
#line 150 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
{
#line 209 "inform7/Chapter 22/Phrase Runtime Context Data.w"
c_s_stage_law = "IV - Action requirement";
int rv = Plugins__Actions__Patterns__compare_specificity(ap1, ap2);
if (rv != 0) return rv;
}
#line 151 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
{
#line 216 "inform7/Chapter 22/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 152 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
return 0;
}
#line 231 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__ensure_avl(rule *R) {
phrase *ph = R->defn_as_phrase;
if (ph) {
ph_runtime_context_data *rcd = &(ph->runtime_context_data);
if (rcd->activity_context_w1 >= 0) {
parse_node *save_cs = current_sentence;
current_sentence = rcd->activity_where;
ph_stack_frame *phsf = &(ph->stack_frame);
Code__Frames__make_current(phsf);
Code__Frames__set_stvol(phsf, R->listed_stv_owners);
rcd->avl =
Code__Activities__Lists__parse(
rcd->activity_context_w1, rcd->activity_context_w2);
current_sentence = save_cs;
}
}
}
#line 272 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__compile_test_head(OUTPUT_STREAM, phrase *ph,
applicability_condition *acl) {
char *identifier = Code__Phrases__identifier(ph);
ph_runtime_context_data *phrcd = &(ph->runtime_context_data);
Code__Rules__compile_constraint(OUT, acl);
int tests = 0;
if (phrcd->during_scene)
{
#line 316 "inform7/Chapter 22/Phrase Runtime Context Data.w"
Plugins__Scenes__test_during_clause(OUT, phrcd->during_scene);
tests++;
}
#line 281 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
if (Plugins__Actions__Patterns__is_valid(&(phrcd->ap)))
{
#line 328 "inform7/Chapter 22/Phrase Runtime Context Data.w"
WRITE("if (");
if (phrcd->never_test_actor)
Plugins__Actions__Patterns__compile_pattern_match(OUT, phrcd->ap, TRUE);
else
Plugins__Actions__Patterns__compile_pattern_match(OUT, phrcd->ap, FALSE);
WRITE(") { ! Runs only when pattern matches\n");
tests++;
if (Plugins__Actions__Patterns__object_based(&(phrcd->ap)))
WRITE("self = noun;\n");
}
#line 282 "inform7/Chapter 22/Phrase Runtime Context Data.w"
else if (phrcd->always_test_actor == TRUE)
{
#line 347 "inform7/Chapter 22/Phrase Runtime Context Data.w"
WRITE("if (actor == player) {\n");
tests++;
}
#line 283 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
if (phrcd->activity_context_w1 >= 0)
{
#line 359 "inform7/Chapter 22/Phrase Runtime Context Data.w"
activity_list *avl = phrcd->avl;
if (avl == NULL)
Problems__sentence_problem(_P_(C22BadWhenWhile),
"I don't understand the 'when/while' clause",
"which should name activities or conditions.");
else {
WRITE("if ");
Code__Activities__compile_activity_list(OUT, avl);
WRITE(" { ! Runs only while condition holds\n");
Code__Activities__Lists__annotate_for_cross_references(avl, ph);
tests++;
}
}
#line 284 "inform7/Chapter 22/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 295 "inform7/Chapter 22/Phrase Runtime Context Data.w"
void Code__Phrases__Context__compile_test_tail(OUTPUT_STREAM, phrase *ph,
applicability_condition *acl) {
char *identifier = Code__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)
Code__Rulebooks__compile_default_outcome(
Code__Rulebooks__get_outcomes(rb), OUT);
}
if (phrcd->activity_context_w1 >= 0)
{
#line 375 "inform7/Chapter 22/Phrase Runtime Context Data.w"
WRITE("} else if (debug_rules > 1) DB_Rule(%s, %d, 'context');\n",
identifier, ph->allocation_id);
}
#line 307 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
if (Plugins__Actions__Patterns__is_valid(&(phrcd->ap)))
{
#line 341 "inform7/Chapter 22/Phrase Runtime Context Data.w"
WRITE("} else if (debug_rules > 1) DB_Rule(%s, %d, 'action');\n",
identifier, ph->allocation_id);
}
#line 308 "inform7/Chapter 22/Phrase Runtime Context Data.w"
else if (phrcd->always_test_actor == TRUE)
{
#line 353 "inform7/Chapter 22/Phrase Runtime Context Data.w"
WRITE("} else if (debug_rules > 1) DB_Rule(%s, %d, 'actor');\n",
identifier, ph->allocation_id);
}
#line 309 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
if (phrcd->during_scene)
{
#line 322 "inform7/Chapter 22/Phrase Runtime Context Data.w"
WRITE("} else if (debug_rules > 1) DB_Rule(%s, %d, 'scene');\n",
identifier, ph->allocation_id);
}
#line 310 "inform7/Chapter 22/Phrase Runtime Context Data.w"
;
}
#line 159 "inform7/Chapter 22/Phrase Type Data.w"
ph_type_data Code__Phrases__TypeData__new(void) {
ph_type_data phtd;
phtd.register_w1 = -1; phtd.register_w2 = -1;
phtd.manner_of_return = DECIDES_NOTHING_MOR;
phtd.return_kind = NULL;
phtd.no_words = 0;
phtd.no_tokens = 0;
phtd.as_say = new_say_details();
phtd.as_inline = new_inline_details();
phtd.now_deprecated = FALSE;
return phtd;
}
#line 179 "inform7/Chapter 22/Phrase Type Data.w"
void Code__Phrases__TypeData__set_mor(ph_type_data *phtd, int mor, kind *K) {
phtd->manner_of_return = mor;
phtd->return_kind = K;
}
int Code__Phrases__TypeData__get_mor(ph_type_data *phtd) {
return phtd->manner_of_return;
}
kind *Code__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 196 "inform7/Chapter 22/Phrase Type Data.w"
char *Code__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 248 "inform7/Chapter 22/Phrase Type Data.w"
kind *Code__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 = Code__Phrases__TypeData__get_return_kind(phtd);
return Kinds__function_kind(j, argument_kinds, R);
}
#line 260 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__contains_variables(ph_type_data *phtd) {
return
Kinds__contains(
Code__Phrases__TypeData__kind(phtd),
CON_KIND_VARIABLE);
}
#line 270 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__tokens_contain_variable(ph_type_data *phtd, int v) {
for (int i=0; i<phtd->no_tokens; i++)
if (Kinds__involves_var(phtd->token_sequence[i].token_kind, v))
return TRUE;
return FALSE;
}
#line 280 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__get_no_tokens(ph_type_data *phtd) {
return phtd->no_tokens;
}
#line 287 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__index_of_token_creating_a_variable(ph_type_data *phtd) {
int i;
for (i=0; i<phtd->no_tokens; i++)
if (Specifications__species_is(phtd->token_sequence[i].to_match,
NEW_LOCAL_VARIABLE_NAME_SPC))
return i;
return -1;
}
#line 302 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__preamble_requires_property_value(ph_type_data *phtd) {
int i;
for (i=0; i<phtd->no_tokens; i++) {
if (Specifications__Storage__get_storage_form(phtd->token_sequence[i].to_match)
== PROPERTY_VALUE_SPC)
return FALSE;
}
return TRUE;
}
#line 320 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__deprecated(ph_type_data *phtd) {
return phtd->now_deprecated;
}
void Code__Phrases__TypeData__deprecate_phrase(ph_type_data *phtd) {
phtd->now_deprecated = TRUE;
}
#line 359 "inform7/Chapter 22/Phrase Type Data.w"
void Code__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) {
Code__LocalVariables__add_call_parameter(phsf,
phtd->token_sequence[i].word_ref1, phtd->token_sequence[i].word_ref2, K);
} else {
local_variable *lvar = Code__LocalVariables__get_ith_parameter(i);
if (lvar) Code__LocalVariables__set_kind(lvar, K);
}
}
if (Kinds__eq(ret, K_nil)) Code__Frames__set_kind_returned(phsf, NULL);
else Code__Frames__set_kind_returned(phsf, ret);
}
#line 390 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__comparison(ph_type_data *phtd1, ph_type_data *phtd2) {
if (phtd1 == phtd2) return EQUAL_PH;
{
#line 406 "inform7/Chapter 22/Phrase Type Data.w"
int i = inline_type_data_comparison(phtd1, phtd2);
if (i != EQUAL_PH) return i;
}
#line 394 "inform7/Chapter 22/Phrase Type Data.w"
;
{
#line 412 "inform7/Chapter 22/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 395 "inform7/Chapter 22/Phrase Type Data.w"
;
{
#line 420 "inform7/Chapter 22/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 396 "inform7/Chapter 22/Phrase Type Data.w"
;
{
#line 433 "inform7/Chapter 22/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(
Text__word_raw_text(phtd1->word_sequence[i]),
Text__word_raw_text(phtd2->word_sequence[i]));
if (x > 0) return AFTER_PH;
if (x < 0) return BEFORE_PH;
}
}
}
#line 397 "inform7/Chapter 22/Phrase Type Data.w"
;
{
#line 461 "inform7/Chapter 22/Phrase Type Data.w"
int i, possibly_subschema = TRUE, possibly_superschema = TRUE;
for (i=0; i<phtd1->no_tokens; i++) {
specification *spec1 = phtd1->token_sequence[i].to_match;
specification *spec2 = phtd2->token_sequence[i].to_match;
{
#line 499 "inform7/Chapter 22/Phrase Type Data.w"
if (((Specifications__get_family(spec1) == MATCHING_FMY) ||
(Specifications__get_family(spec2) == MATCHING_FMY)) &&
(Specifications__get_family(spec1) != Specifications__get_family(spec2))) {
possibly_subschema = FALSE; possibly_superschema = 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 465 "inform7/Chapter 22/Phrase Type Data.w"
;
}
if ((possibly_subschema) || (possibly_superschema))
{
#line 482 "inform7/Chapter 22/Phrase Type Data.w"
if ((phtd1->manner_of_return != phtd2->manner_of_return) ||
((Kinds__eq(phtd1->return_kind, phtd2->return_kind) == FALSE) &&
(Kinds__definite(phtd1->return_kind))))
return CONFLICTED_PH;
}
#line 468 "inform7/Chapter 22/Phrase Type Data.w"
;
if (possibly_subschema) return SUBSCHEMA_PH;
if (possibly_superschema) return SUPERSCHEMA_PH;
}
#line 398 "inform7/Chapter 22/Phrase Type Data.w"
;
return INCOMPARABLE_PH;
}
#line 518 "inform7/Chapter 22/Phrase Type Data.w"
say_details 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 Code__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 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 Code__Phrases__TypeData__is_a_say_phrase(phrase *ph) {
if ((ph) && (ph->type_data.as_say.say_phrase)) return TRUE;
return FALSE;
}
int Code__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 Code__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 Code__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 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 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 Code__Phrases__TypeData__ssp_matches(ph_type_data *phtd, int ssp_tok, int list_pos,
int *w1, int *w2) {
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;
*w1 = phtd->register_w1 + 1;
*w2 = phtd->register_w2;
return TRUE;
}
#line 640 "inform7/Chapter 22/Phrase Type Data.w"
inline_details 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 657 "inform7/Chapter 22/Phrase Type Data.w"
int no_lets_made = 0;
void Code__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 = Text__word_text(only_in);
}
#line 672 "inform7/Chapter 22/Phrase Type Data.w"
void 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 685 "inform7/Chapter 22/Phrase Type Data.w"
void Code__Phrases__TypeData__make_inline(ph_type_data *phtd) {
phtd->as_inline.invoked_inline_not_as_call = TRUE;
}
int Code__Phrases__TypeData__invoked_inline(phrase *ph) {
return ph->type_data.as_inline.invoked_inline_not_as_call;
}
#line 696 "inform7/Chapter 22/Phrase Type Data.w"
int Code__Phrases__TypeData__is_a_let_assignment(phrase *ph) {
if (ph->type_data.as_inline.let_phrase == ASSIGNMENT_LET_PHRASE) return TRUE;
return FALSE;
}
int Code__Phrases__TypeData__is_a_let_equation(phrase *ph) {
if (ph->type_data.as_inline.let_phrase == EQUATION_LET_PHRASE) return TRUE;
return FALSE;
}
int Code__Phrases__TypeData__arithmetic_operation(phrase *ph) {
return ph->type_data.as_inline.arithmetical_operation;
}
int Code__Phrases__TypeData__is_assignment_phrase(phrase *ph) {
return ph->type_data.as_inline.assignment_phrase;
}
char *Code__Phrases__TypeData__only_in(phrase *ph) {
if (ph) return ph->type_data.as_inline.only_in_loop;
return NULL;
}
int Code__Phrases__TypeData__block_follows(phrase *ph) {
return ph->type_data.as_inline.block_follows;
}
#line 732 "inform7/Chapter 22/Phrase Type Data.w"
int Code__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 746 "inform7/Chapter 22/Phrase Type Data.w"
int 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 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__log(ph_type_data *phtd) {
LOG(" PHTD: register as <$W>\n %s\n",
phtd->register_w1, phtd->register_w2,
Code__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 27 "inform7/Chapter 22/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 ", Text__word_text(phtd->word_sequence[i]));
LOG("(%d words)\n", phtd->no_words);
}
#line 18 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
{
#line 39 "inform7/Chapter 22/Describing Phrase Type Data.w"
int i;
for (i=0; i<phtd->no_tokens; i++)
LOG(" #%d: \"$W\" = $S\n", i,
phtd->token_sequence[i].word_ref1, phtd->token_sequence[i].word_ref2,
phtd->token_sequence[i].to_match);
}
#line 19 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
log_inline_details(phtd->as_inline);
log_say_details(phtd->as_say);
}
#line 48 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__log_briefly(ph_type_data *phtd) {
LOG("\"$W\"", phtd->register_w1, phtd->register_w2);
switch(phtd->manner_of_return) {
case DECIDES_CONDITION_MOR: LOG("(=condition)"); break;
case DECIDES_VALUE_MOR: LOG("(=$u)", phtd->return_kind); break;
}
}
#line 70 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__write_HTML_representation(OUTPUT_STREAM,
ph_type_data *phtd, int paste_format, invocation *inv) {
int seq_from = 0, seq_to = phtd->no_words;
int writing_a_say = 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 98 "inform7/Chapter 22/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 126 "inform7/Chapter 22/Describing Phrase Type Data.w"
switch (paste_format) {
case INDEX_PHRASE_FORMAT:
if (writing_a_say == FALSE) WRITE("(");
if (inv) {
specification *found = Code__Invocations__get_token_as_parsed(inv, ix);
Text__print_text_to_stream(found->word_ref1, found->word_ref2, OUT);
WRITE(" - ");
Specifications__Matching__note_inv_token_text(found);
}
{
#line 146 "inform7/Chapter 22/Describing Phrase Type Data.w"
if (phtd->token_sequence[ix].name_of_a_kind) {
WRITE("<font color=\"#800060\">");
WRITE("name of kind");
WRITE("</font>");
} else {
specification *spec = phtd->token_sequence[ix].to_match;
if (Specifications__Values__is_generic_CONSTANT(spec)) {
WRITE("<font color=\"#4040ff\">");
Kinds__Textual__write(OUT, Specifications__get_kind(spec));
WRITE("</font>");
} else if ((Specifications__Values__is_actual_CONSTANT(spec)) ||
(Specifications__species_is(spec, DESCRIPTION_SPC))) {
WRITE("<font color=\"#4040ff\">");
Text__print_text_to_stream(spec->word_ref1, spec->word_ref2, OUT);
WRITE("</font>");
} else if (Specifications__species_is(spec, TRY_ACTION_SPC)) {
WRITE("<i><font color=\"#ff4040\">an action</font></i>");
} else if (Specifications__family_is(spec, COMMAND_FMY)) {
WRITE("<i><font color=\"#ff4040\">a phrase</font></i>");
} else {
WRITE("<i>");
WRITE("<font color=\"#ff4040\">");
Specifications__write_out_in_English(OUT, spec);
WRITE("</font>");
WRITE("</i>");
}
}
}
#line 135 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
if (writing_a_say == FALSE) WRITE(")");
break;
case PASTE_PHRASE_FORMAT:
WRITE("...");
break;
}
}
#line 103 "inform7/Chapter 22/Describing Phrase Type Data.w"
else
{
#line 111 "inform7/Chapter 22/Describing Phrase Type Data.w"
char *p = Text__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 105 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
}
}
#line 86 "inform7/Chapter 22/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>");
}
epilogue_for_say_HTML(OUT, phtd->as_say, paste_format);
}
#line 178 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__inv_write_HTML_representation(OUTPUT_STREAM, invocation *inv) {
phrase *ph = inv->phrase_invoked;
if (ph) {
ph_type_data *phtd = &(ph->type_data);
if (ph->ph_documentation_symbol_wn >= 0)
Index__doc_link_to(OUT, Text__word_raw_text(ph->ph_documentation_symbol_wn), -1);
else
Index__link_to(OUT, ph->declaration_node->word_ref1, FALSE);
WRITE(" ");
Code__Phrases__TypeData__write_HTML_representation(OUT, phtd, INDEX_PHRASE_FORMAT, inv);
WRITE(" ");
if ((Code__Invocations__test_flag(inv, PASSED_INVFLAG)) ||
(Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG)))
WRITE("<img border=0 src=inform:/doc_images/tick.png>");
else if ((Code__Invocations__test_flag(inv, GROSSLY_FAILED_INVFLAG)) ||
(Code__Invocations__test_flag(inv, INTERESTING_PROBLEM_INVFLAG)))
WRITE("<img border=0 src=inform:/doc_images/cross.png>");
else if (Code__Invocations__test_flag(inv, TESTED_INVFLAG) == FALSE)
WRITE("<img border=0 src=inform:/doc_images/greytick.png>");
else
WRITE("<img border=0 src=inform:/doc_images/cross.png>");
}
}
#line 206 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__write_index_representation(ph_type_data *phtd, phrase *ph) {
if (phtd->manner_of_return == DECIDES_CONDITION_MOR)
INDEX("<i>if</i> ");
Code__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__definite(phtd->return_kind) == FALSE) INDEX("value");
else Kinds__Textual__write(ifl, phtd->return_kind);
INDEX("</i>");
int w = Code__Phrases__Usage__get_equation_form(&(ph->usage_data));
if (w >= 0) {
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>y</i>&nbsp;=&nbsp;<b>");
Text__print_raw_text_to_stream(w, w, ifl);
INDEX("</b>(<i>x</i>)");
}
}
}
#line 231 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__write_reveal_box(ph_type_data *phtd, phrase *ph) {
{
#line 246 "inform7/Chapter 22/Describing Phrase Type Data.w"
TEMPORARY_STREAM;
Code__Phrases__write_HTML_representation(TEMP, ph, PASTE_PHRASE_FORMAT);
Formats__HTML__Javascript__paste(ifl, -1, -1, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
INDEX("&nbsp;");
}
#line 232 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
Code__Phrases__TypeData__write_index_representation(phtd, ph);
Code__Phrases__Options__index(&(ph->options_data));
{
#line 256 "inform7/Chapter 22/Describing Phrase Type Data.w"
if (ph->ph_documentation_symbol_wn >= 0) {
INDEX("</p>");
Index__doc_fragment(Text__word_raw_text(ph->ph_documentation_symbol_wn));
INDEX("<p><b>See</b> ");
Index__doc_fully_link(Text__word_raw_text(ph->ph_documentation_symbol_wn));
}
}
#line 235 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
{
#line 266 "inform7/Chapter 22/Describing Phrase Type Data.w"
int w = Code__Phrases__Usage__get_equation_form(&(ph->usage_data));
if (w >= 0) {
INDEX("</p><p><b>In equations:</b> write as ");
Formats__HTML__Javascript__paste(ifl, w, w, NULL);
INDEX("&nbsp;");
Text__print_raw_text_to_stream(w, w, ifl);
INDEX("()");
}
}
#line 236 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
{
#line 278 "inform7/Chapter 22/Describing Phrase Type Data.w"
if (ph->usage_data.constant_phrase_holder) {
int n1 = ph->usage_data.constant_phrase_holder->word_ref1;
int n2 = ph->usage_data.constant_phrase_holder->word_ref2;
INDEX("</p><p><b>Name:</b> ");
Formats__HTML__Javascript__paste(ifl, n1, n2, NULL);
INDEX("&nbsp;");
Text__print_raw_text_to_stream(n1, n2, ifl);
}
}
#line 237 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
{
#line 291 "inform7/Chapter 22/Describing Phrase Type Data.w"
if (Code__Phrases__TypeData__is_a_say_phrase(ph) == FALSE) {
INDEX("</p><p><b>Kind:</b> ");
Kinds__Textual__write(ifl, Code__Phrases__TypeData__kind(phtd));
}
}
#line 238 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
INDEX("</p>\n");
{
#line 299 "inform7/Chapter 22/Describing Phrase Type Data.w"
if (Code__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 240 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
}
#line 314 "inform7/Chapter 22/Describing Phrase Type Data.w"
void 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 ", Text__word_text(phtd->word_sequence[j]));
}
WRITE(":\n");
}
#line 341 "inform7/Chapter 22/Describing Phrase Type Data.w"
void Code__Phrases__TypeData__parse(ph_type_data *phtd, int x1, int x2, int *ow1, int *ow2) {
int say_flag = FALSE; /* is this going to be a "say" phrase? */
if (x1<=x2) x1 = phtd_parse_return_data(phtd, x1, x2); /* trim return data from the front */
if (x1<=x2) Index__DocReferences__position_of_symbol(&x1, &x2); /* trim documentation ref from the back */
if (x1<=x2) x2 = phtd_parse_doodads(phtd, x1, x2, &say_flag); /* and other doodads from the back */
int cw = -1; /* word number of first comma */
{
#line 366 "inform7/Chapter 22/Describing Phrase Type Data.w"
int i, bl = 0;
for (i=x1; i<=x2; i++) {
if ((Text__word(i) == OPENBRACE_V) || (Text__word(i) == OPENBRACKET_V)) bl++;
if ((Text__word(i) == CLOSEBRACE_V) || (Text__word(i) == CLOSEBRACKET_V)) bl--;
if ((Text__word(i) == COMMA_V) && (bl == 0) && (i>x1) && (i<x2)) { cw = i; break; }
}
}
#line 349 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
if (cw >= 0) {
int comma_presages_options = TRUE;
{
#line 376 "inform7/Chapter 22/Describing Phrase Type Data.w"
if ((parse_nt_against_word_range(control_structure_phrase_NTM, x1, x2, NULL, NULL)) &&
((most_recent_result_p == if_CSP) ||
(most_recent_result_p == switch_CSP) ||
(most_recent_result_p == otherwise_if_CSP)))
comma_presages_options = FALSE;
}
#line 352 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
if (comma_presages_options) {
if (say_flag)
{
#line 387 "inform7/Chapter 22/Describing Phrase Type Data.w"
Problems__sentence_problem(_P_(C22SayWithPhraseOptions),
"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 354 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
*ow1 = cw + 1; *ow2 = x2; /* the text after the comma */
x2 = cw - 1; /* trim the preamble range to to the text before the comma */
}
}
phtd->register_w1 = x1; phtd->register_w2 = x2;
phtd_parse_word_sequence(phtd, x1, x2);
}
#line 430 "inform7/Chapter 22/Describing Phrase Type Data.w"
int phrase_preamble_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 434 "inform7/Chapter 22/Describing Phrase Type Data.w"
int to_preamble_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 446 "inform7/Chapter 22/Describing Phrase Type Data.w"
#line 451 "inform7/Chapter 22/Describing Phrase Type Data.w"
int say_preamble_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 462 "inform7/Chapter 22/Describing Phrase Type Data.w"
#line 476 "inform7/Chapter 22/Describing Phrase Type Data.w"
int to_return_data_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 484 "inform7/Chapter 22/Describing Phrase Type Data.w"
int return_kind_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 492 "inform7/Chapter 22/Describing Phrase Type Data.w"
*XP = K_number;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C22UnknownValueToDecide));
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 487 "inform7/Chapter 22/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 488 "inform7/Chapter 22/Describing Phrase Type Data.w"
#line 505 "inform7/Chapter 22/Describing Phrase Type Data.w"
int no_truth_state_returns = 0;
int phtd_parse_return_data(ph_type_data *phtd, int x1, int x2) {
phtd->return_kind = NULL;
if (parse_nt_against_word_range(to_return_data_NTM, x1, x2, NULL, NULL)) {
GET_RW(to_return_data_NTM, 1, x1, x2);
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) Code__Phrases__TypeData__set_mor(phtd, mor, K);
} else internal_error("to phrase without to");
if (Kinds__eq(phtd->return_kind, K_truth_state)) {
if (no_truth_state_returns++ > 0)
Problems__sentence_problem(_P_(C22TruthStateToDecide),
"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 x1;
}
#line 535 "inform7/Chapter 22/Describing Phrase Type Data.w"
int phtd_parse_doodads(ph_type_data *phtd, int w1, int w2, int *say_flag) {
operation_NTMV = -1; assignment_NTMV = FALSE; deprecated_NTMV = FALSE; run_on_NTMV = FALSE;
parse_nt_against_word_range(phrase_preamble_NTM, w1, w2, NULL, NULL); /* guaranteed to match any non-empty text */
if (most_recent_result == SAY_ANN) { GET_RW(say_preamble_NTM, 1, w1, w2); }
else { GET_RW(to_preamble_NTM, 1, w1, w2); }
if (deprecated_NTMV) Code__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 565 "inform7/Chapter 22/Describing Phrase Type Data.w"
int x1;
GET_RW(to_preamble_NTM, 2, x1, x1);
only_in = x1;
}
#line 547 "inform7/Chapter 22/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 572 "inform7/Chapter 22/Describing Phrase Type Data.w"
*say_flag = TRUE;
int x1, cs = -1, pos = -1, at = -1, cat = -1;
switch (say_ann_NTMV) {
case CONTROL_SANN: cs = control_NTMV; break;
case BEGIN_SANN: pos = SSP_START; GET_RW(say_preamble_NTM, 2, x1, x1); at = x1; break;
case CONTINUE_SANN: pos = SSP_MIDDLE; GET_RW(say_preamble_NTM, 2, x1, x1); at = x1; break;
case ENDM_SANN: pos = SSP_END; GET_RW(say_preamble_NTM, 2, x1, x1); at = x1;
GET_RW(say_preamble_NTM, 3, x1, x1); cat = x1;
break;
case END_SANN: pos = SSP_END; GET_RW(say_preamble_NTM, 2, x1, x1); at = x1; break;
}
Code__Phrases__TypeData__make_sd(&(phtd->as_say), run_on_NTMV, cs, pos, at, cat);
}
#line 553 "inform7/Chapter 22/Describing Phrase Type Data.w"
; break;
}
Code__Phrases__TypeData__make_id(&(phtd->as_inline),
operation_NTMV, assignment_NTMV, let, blk, only_in);
return w2;
}
#line 599 "inform7/Chapter 22/Describing Phrase Type Data.w"
int phrase_definition_word_or_token_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 621 "inform7/Chapter 22/Describing Phrase Type Data.w"
*X = NOT_APPLICABLE;
Problems__sentence_problem(_P_(C22TokenWithEmptyBrackets),
"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 600 "inform7/Chapter 22/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 631 "inform7/Chapter 22/Describing Phrase Type Data.w"
*X = NOT_APPLICABLE;
Problems__sentence_problem(_P_(C22TokenWithoutCloseBracket),
"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 602 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 641 "inform7/Chapter 22/Describing Phrase Type Data.w"
*X = NOT_APPLICABLE;
Problems__sentence_problem(_P_(C22TokenWithoutOpenBracket),
"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 603 "inform7/Chapter 22/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 605 "inform7/Chapter 22/Describing Phrase Type Data.w"
#line 610 "inform7/Chapter 22/Describing Phrase Type Data.w"
int phrase_token_declaration_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 652 "inform7/Chapter 22/Describing Phrase Type Data.w"
*X = NOT_APPLICABLE;
Problems__sentence_problem(_P_(C22TokenWithNestedBrackets),
"the name of the token inside the brackets '(' and ')' and before the "
"hyphen '-' itself contains another open bracket '('",
"which is not allowed.");
}
#line 611 "inform7/Chapter 22/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 = RP[1]; token_nameflag_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; *XP = RP[1]; token_nameflag_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 661 "inform7/Chapter 22/Describing Phrase Type Data.w"
*X = NOT_APPLICABLE;
int x1, x2;
GET_RW(phrase_token_declaration_NTM, 2, x1, x2);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, x1, x2);
Problems__handmade_problem(_P_(C22BadTypeIndication));
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 614 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = FALSE; *XP = RP[1]; token_nameflag_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 676 "inform7/Chapter 22/Describing Phrase Type Data.w"
LOG("On $W\n", w1, w2);
*X = NOT_APPLICABLE;
Problems__sentence_problem(_P_(C22TokenMisunderstood),
"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 616 "inform7/Chapter 22/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 617 "inform7/Chapter 22/Describing Phrase Type Data.w"
#line 693 "inform7/Chapter 22/Describing Phrase Type Data.w"
void phtd_parse_word_sequence(ph_type_data *phtd, int w1, int w2) {
phtd->no_tokens = 0;
phtd->no_words = 0;
int i = w1;
while (i <= w2) {
int word_to_add = 0; /* redundant assignment to keep |gcc| happy */
parse_nt_against_word_range(phrase_definition_word_or_token_NTM, i, w2, NULL, NULL);
switch (most_recent_result) {
case NOT_APPLICABLE: return; /* a problem message has been issued */
case TRUE:
{
#line 726 "inform7/Chapter 22/Describing Phrase Type Data.w"
if (token_form_NTMV == NOT_APPLICABLE) return; /* a problem message has been issued */
specification *spec = most_recent_result_p; /* what is to be matched */
int tw1 = -1, tw2 = -1;
if (token_form_NTMV) GET_RW(phrase_token_declaration_NTM, 1, tw1, tw2); /* the name */
GET_RW(phrase_definition_word_or_token_NTM, 1, i, w2); /* move past this token */
{
#line 754 "inform7/Chapter 22/Describing Phrase Type Data.w"
if ((Specifications__species_is(spec, DESCRIPTION_SPC)) &&
(Specifications__Conditions__get_described_instance(spec))) {
Problems__sentence_problem(_P_(C22TokenWithStipulations),
"a bracketed token must be a general description",
"or else a single specific name, but not a specific name with "
"stipulations attached.");
return;
}
}
#line 735 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
{
#line 766 "inform7/Chapter 22/Describing Phrase Type Data.w"
if ((!((Specifications__species_is(spec, DESCRIPTION_SPC)) ||
(Specifications__species_is(spec, CONSTANT_SPC)))) &&
(phtd->as_inline.invoked_inline_not_as_call == FALSE)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, spec->word_ref1, spec->word_ref2);
Problems__handmade_problem(_P_(C22NoninlineUsesNonvalues));
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 736 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
{
#line 742 "inform7/Chapter 22/Describing Phrase Type Data.w"
phrase_token pht;
pht.name_of_a_kind = FALSE;
if (token_nameflag_NTMV) pht.name_of_a_kind = TRUE;
pht.word_ref1 = tw1; pht.word_ref2 = tw2;
pht.to_match = spec;
pht.token_kind = Specifications__get_kind_referred_to(spec);
phtd->token_sequence[phtd->no_tokens] = pht;
word_to_add = phtd->no_tokens++;
}
#line 737 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
}
#line 703 "inform7/Chapter 22/Describing Phrase Type Data.w"
; break;
case FALSE:
{
#line 721 "inform7/Chapter 22/Describing Phrase Type Data.w"
word_to_add = i++;
}
#line 704 "inform7/Chapter 22/Describing Phrase Type Data.w"
; break;
}
if (phtd->no_words >= MAX_WORDS_PER_PHRASE) {
Problems__sentence_problem(_P_(C22PhraseTooLong),
"this phrase has too many words",
"and needs to be simplified.");
return;
}
phtd->word_sequence[phtd->no_words++] = word_to_add;
}
{
#line 786 "inform7/Chapter 22/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 += find_kind_variable_domains(phtd->token_sequence[i].token_kind,
usages, declarations);
if (t > 0) {
for (i=1; i<=26; i++)
if ((usages[i] > 0) && (declarations[i] == NULL))
{
#line 805 "inform7/Chapter 22/Describing Phrase Type Data.w"
Problems__sentence_problem(_P_(C22UndeclaredKindVariable),
"this phrase uses a kind variable which is not declared",
"which is not allowed.");
}
#line 796 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
for (i=0; i<phtd->no_tokens; i++)
if (phtd->token_sequence[i].token_kind)
{
#line 828 "inform7/Chapter 22/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__Values__new_generic_CONSTANT(substituted);
}
#line 799 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
}
}
#line 715 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
}
#line 840 "inform7/Chapter 22/Describing Phrase Type Data.w"
int 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 872 "inform7/Chapter 22/Describing Phrase Type Data.w"
usages[N]++;
kind *dec = Kinds__get_variable_stipulation(K);
if (dec) {
if (declarations[N]) {
Problems__sentence_problem(_P_(C22DoublyDeclaredKindVariable),
"this phrase declares the same kind variable more than once",
"and ought to declare each variable once each.");
}
declarations[N] = dec;
}
}
#line 846 "inform7/Chapter 22/Describing Phrase Type Data.w"
;
}
if (Kinds__is_proper_constructor(K)) {
int a = Kinds__arity_of_constructor(K);
if (a == 1)
t += 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 += find_kind_variable_domains(X, usages, declarations);
t += find_kind_variable_domains(Y, usages, declarations);
}
}
}
return t;
}
#line 888 "inform7/Chapter 22/Describing Phrase Type Data.w"
char *Code__Phrases__TypeData__incipit(phrase *ph) {
if ((ph == NULL) ||
(ph->type_data.no_words == 0) ||
(ph->type_data.word_sequence[0] < MAX_TOKENS_PER_PHRASE)) return "";
return Text__word_text(ph->type_data.word_sequence[0]);
}
#line 47 "inform7/Chapter 22/Phrase Options.w"
ph_options_data Code__Phrases__Options__new(int w1, int w2) {
ph_options_data phod;
phod.no_options_permitted = 0;
phod.multiple_options_permitted = FALSE;
phod.options_w1 = w1; phod.options_w2 = w2;
return phod;
}
int Code__Phrases__Options__allows_options(ph_options_data *phod) {
if (phod->no_options_permitted > 0) return TRUE;
return FALSE;
}
#line 66 "inform7/Chapter 22/Phrase Options.w"
int Code__Phrases__Options__parse(ph_options_data *phod, int w1, int w2) {
int i;
for (i=0; i<phod->no_options_permitted; i++) {
phrase_option *po = phod->options_permitted[i];
if (Text__compare_word_range(w1, w2, po->word_ref1, po->word_ref2))
return (1 << i);
}
return -1;
}
#line 79 "inform7/Chapter 22/Phrase Options.w"
void Code__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> ");
}
Formats__HTML__Javascript__paste(ifl, po->word_ref1, po->word_ref2, NULL);
INDEX("&nbsp;");
Text__print_raw_text_to_stream(po->word_ref1, po->word_ref2, ifl);
if (i < phod->no_options_permitted-1) INDEX(",<br>");
INDEX("\n");
}
}
#line 100 "inform7/Chapter 22/Phrase Options.w"
ph_options_data *phod_being_parsed = NULL;
phrase *ph_being_parsed = NULL;
ph_options_data Code__Phrases__Options__parse_declared_options(int w1, int w2) {
ph_options_data phod = Code__Phrases__Options__new(w1, w2);
if (w1 >= 0) {
phod_being_parsed = &phod;
parse_nt_against_word_range(phrase_option_declaration_list_NTM, w1, w2, NULL, NULL);
if (most_recent_result) phod.multiple_options_permitted = TRUE;
}
return phod;
}
#line 137 "inform7/Chapter 22/Phrase Options.w"
int phrase_option_declaration_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 141 "inform7/Chapter 22/Phrase Options.w"
int phrase_option_declaration_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 147 "inform7/Chapter 22/Phrase Options.w"
int phrase_option_declaration_setting_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = FALSE; if (!preform_lookahead_mode) phod_add_phrase_option(phod_being_parsed, w1, w2);;
#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 22/Phrase Options.w"
#line 154 "inform7/Chapter 22/Phrase Options.w"
int too_many_POs_error = FALSE;
void phod_add_phrase_option(ph_options_data *phod, int w1, int w2) {
LOGIF(PHRASE_CREATIONS, "Adding phrase option <$W>\n", w1, w2);
if (phod->no_options_permitted >= MAX_OPTIONS_PER_PHRASE) {
if (too_many_POs_error == FALSE)
Problems__sentence_problem(_P_(C22TooManyPhraseOptions),
"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->word_ref1 = w1; po->word_ref2 = w2;
phod->options_permitted[phod->no_options_permitted++] = po;
}
#line 193 "inform7/Chapter 22/Phrase Options.w"
int phod_being_parsed_silently = FALSE; /* context for the grammar below */
int Code__Phrases__Options__parse_invoked_options(invocation *inv, int silently) {
phrase *ph = Code__Invocations__get_phrase_invoked(inv);
int w1 = -1, w2 = -1;
Code__Invocations__get_phrase_options(inv, &w1, &w2);
ph_being_parsed = ph;
phod_being_parsed = &(ph_being_parsed->options_data);
int bitmap = 0;
int pc = problem_count;
{
#line 216 "inform7/Chapter 22/Phrase Options.w"
int s = phod_being_parsed_silently;
phod_being_parsed_silently = silently;
if (parse_nt_against_word_range(phrase_option_list_NTM, w1, w2, NULL, NULL)) bitmap = most_recent_result;
phod_being_parsed_silently = s;
if ((problem_count == pc) &&
(phod_being_parsed->multiple_options_permitted == FALSE))
{
#line 235 "inform7/Chapter 22/Phrase Options.w"
if ((bitmap & (bitmap - 1)) != 0) {
if (silently == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_phrase(3, ph);
Problems__quote_words(4,
phod_being_parsed->options_w1, phod_being_parsed->options_w2);
Problems__handmade_problem(_P_(C22PhraseOptionsExclusive));
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 223 "inform7/Chapter 22/Phrase Options.w"
;
}
#line 206 "inform7/Chapter 22/Phrase Options.w"
;
Code__Invocations__set_phrase_options_bitmap(inv, bitmap);
if (problem_count > pc) return FALSE;
return TRUE;
}
#line 255 "inform7/Chapter 22/Phrase Options.w"
int phrase_option_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 259 "inform7/Chapter 22/Phrase Options.w"
int phrase_option_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 263 "inform7/Chapter 22/Phrase Options.w"
int phrase_option_setting_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 271 "inform7/Chapter 22/Phrase Options.w"
if ((!preform_lookahead_mode) && (!phod_being_parsed_silently)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_phrase(3, ph_being_parsed);
Problems__quote_words(4,
phod_being_parsed->options_w1, phod_being_parsed->options_w2);
if (phod_being_parsed->no_options_permitted > 1) {
Problems__handmade_problem(_P_(C22NotAPhraseOption));
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__handmade_problem(_P_(C22NotTheOnlyPhraseOption));
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 266 "inform7/Chapter 22/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 267 "inform7/Chapter 22/Phrase Options.w"
#line 296 "inform7/Chapter 22/Phrase Options.w"
int phrase_option_NTMR(int w1, int w2, int *X, void **XP) {
#line 297 "inform7/Chapter 22/Phrase Options.w"
int bitmap = Code__Phrases__Options__parse(phod_being_parsed, w1, w2);
if (bitmap == -1) return FALSE;
*X = bitmap; return TRUE;
}
#line 103 "inform7/Chapter 22/Local Variables.w"
locals_slate Code__LocalVariables__blank_slate(void) {
locals_slate slate;
slate.local_variable_allocation = NULL;
slate.it_pseudonym_w1 = -1; slate.it_pseudonym_w2 = -1;
slate.it_variable_exists = FALSE; slate.its_form_allowed = FALSE;
return slate;
}
#line 116 "inform7/Chapter 22/Local Variables.w"
void Code__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 131 "inform7/Chapter 22/Local Variables.w"
local_variable *add_to_locals_slate(locals_slate *slate, int purpose, int w1, int w2,
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 149 "inform7/Chapter 22/Local Variables.w"
local_variable *find = slate->local_variable_allocation;
if (find == NULL) {
{
#line 171 "inform7/Chapter 22/Local Variables.w"
lvar = CREATE(local_variable);
lvar->next = NULL;
}
#line 151 "inform7/Chapter 22/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 171 "inform7/Chapter 22/Local Variables.w"
lvar = CREATE(local_variable);
lvar->next = NULL;
}
#line 160 "inform7/Chapter 22/Local Variables.w"
;
find->next = lvar;
break;
}
find = find->next;
}
}
}
#line 136 "inform7/Chapter 22/Local Variables.w"
else
{
#line 171 "inform7/Chapter 22/Local Variables.w"
lvar = CREATE(local_variable);
lvar->next = NULL;
}
#line 137 "inform7/Chapter 22/Local Variables.w"
;
if (override_index >= 0) ix = override_index;
{
#line 177 "inform7/Chapter 22/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->kind_as_declared = K;
lvar->protected = TRUE;
lvar->parsed_recently = FALSE;
lvar->comment_on_use = NULL;
if (w1 >= 0) {
if (parse_nt_against_word_range(unsuitable_name_for_locals_NTM, w1, w2, NULL, NULL))
{
#line 209 "inform7/Chapter 22/Local Variables.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C22CalledThe));
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 199 "inform7/Chapter 22/Local Variables.w"
;
if (w2 > w1) Text__Languages__remove_the(&w1, &w2);
}
lvar->varname_w1 = w1; lvar->varname_w2 = w2;
lvar->name_hash = 0;
if (w1 >= 0) lvar->name_hash = Semantics__Nouns__ExcerptMeanings__hash_code(w1, w2);
}
#line 139 "inform7/Chapter 22/Local Variables.w"
;
Specifications__warn_expression_cache(); /* the range of parsing possibilities has changed */
return lvar;
}
#line 222 "inform7/Chapter 22/Local Variables.w"
local_variable *Code__LocalVariables__add_call_parameter(ph_stack_frame *phsf,
int w1, int w2, kind *K) {
local_variable *lvar = add_to_locals_slate(&(phsf->local_value_variables),
TOKEN_CALL_PARAMETER_LV, w1, w2, K, NULL, -1);
LOGIF(LOCAL_VARIABLES, "Call parameter $k added\n", lvar);
return lvar;
}
#line 233 "inform7/Chapter 22/Local Variables.w"
int Code__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 243 "inform7/Chapter 22/Local Variables.w"
local_variable *Code__LocalVariables__new(int w1, int w2, kind *K) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf == NULL) internal_error("tried to add let value without stack frame");
local_variable *lvar = add_to_locals_slate(&(phsf->local_value_variables),
LET_VALUE_LV, w1, w2, K, NULL, -1);
LOGIF(LOCAL_VARIABLES, "Let value $k allocated\n", lvar);
return lvar;
}
#line 257 "inform7/Chapter 22/Local Variables.w"
local_variable *Code__LocalVariables__add_internal(locals_slate *slate,
char *name, int purpose) {
local_variable *lvar = find_i6_var(slate, name, purpose);
if (lvar == NULL) lvar = add_to_locals_slate(slate, purpose, -1, -1, NULL, name, -1);
return lvar;
}
local_variable *Code__LocalVariables__add_internal_local(char *name) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf)
return Code__LocalVariables__add_internal(&(phsf->local_value_variables), name,
INTERNAL_USE_LV);
return NULL;
}
local_variable *Code__LocalVariables__add_named_call(char *name) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf)
return Code__LocalVariables__add_internal(&(phsf->local_value_variables), name,
OTHER_CALL_PARAMETER_LV);
return NULL;
}
void Code__LocalVariables__add_internal_local_c(char *name, char *comment) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf) {
local_variable *lvar =
Code__LocalVariables__add_internal(&(phsf->local_value_variables),
name, INTERNAL_USE_LV);
lvar->comment_on_use = comment;
}
}
#line 294 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__add_table_lookup(void) {
Code__LocalVariables__add_internal_local_c("ct_0", "currently selected table");
Code__LocalVariables__add_internal_local_c("ct_1", "currently selected row");
LOGIF(LOCAL_VARIABLES, "Stack frame acquires CT locals\n");
}
#line 304 "inform7/Chapter 22/Local Variables.w"
void Code__Frames__options_parameter_is_needed(ph_stack_frame *phsf) {
Code__LocalVariables__add_internal(&(phsf->local_value_variables),
"phrase_options", OTHER_CALL_PARAMETER_LV);
}
#line 314 "inform7/Chapter 22/Local Variables.w"
void Code__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_w1 = -1; lvar->varname_w2 = -1; lvar->name_hash = 0;
lvar->block_scope = 0;
}
#line 325 "inform7/Chapter 22/Local Variables.w"
void Code__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))
Code__LocalVariables__deallocate(lvar);
}
#line 335 "inform7/Chapter 22/Local Variables.w"
int Code__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 355 "inform7/Chapter 22/Local Variables.w"
void Code__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 = add_to_locals_slate(slate_to,
lvar->lv_purpose, lvar->varname_w1, lvar->varname_w2, 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_w1 = slate_from->it_pseudonym_w1;
slate_to->it_pseudonym_w2 = slate_from->it_pseudonym_w2;
phsf_to->local_stvol = phsf_from->local_stvol;
}
#line 379 "inform7/Chapter 22/Local Variables.w"
local_variable *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 391 "inform7/Chapter 22/Local Variables.w"
local_variable *Code__LocalVariables__by_name(char *name) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf == NULL) return FALSE;
return find_i6_var(&(phsf->local_value_variables), name, INTERNAL_USE_LV);
}
#line 400 "inform7/Chapter 22/Local Variables.w"
int Code__LocalVariables__are_we_using_table_lookup(void) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf == NULL) return FALSE;
if (find_i6_var(&(phsf->local_value_variables), "ct_0", INTERNAL_USE_LV)) return TRUE;
return FALSE;
}
#line 412 "inform7/Chapter 22/Local Variables.w"
local_variable *Code__LocalVariables__get_ith_parameter(int i) {
ph_stack_frame *phsf = Code__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 436 "inform7/Chapter 22/Local Variables.w"
local_variable *Code__LocalVariables__parse(ph_stack_frame *phsf, int w1, int w2) {
if (phsf == NULL) return NULL;
local_variable *lvar = Code__LocalVariables__parse_inner(phsf, w1, w2);
if (lvar) lvar->parsed_recently = TRUE;
return lvar;
}
local_variable *Code__LocalVariables__parse_inner(ph_stack_frame *phsf, int w1, int w2) {
if ((phsf->local_value_variables.it_variable_exists) && (parse_nt_against_word_range(pronoun_NTM, w1, w2, NULL, NULL)))
return Code__LocalVariables__it_variable();
if (parse_nt_against_word_range(definite_article_NTM, w1, w2, NULL, NULL)) return NULL;
Text__Languages__remove_the(&w1, &w2);
if ((phsf->local_value_variables.it_pseudonym_w1 >= 0) &&
(Text__compare_word_range(w1, w2,
phsf->local_value_variables.it_pseudonym_w1,
phsf->local_value_variables.it_pseudonym_w2)))
return Code__LocalVariables__it_variable();
{
#line 468 "inform7/Chapter 22/Local Variables.w"
int h = Semantics__Nouns__ExcerptMeanings__hash_code(w1, w2);
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
if ((lvar->varname_w1 >= 0) &&
(h == lvar->name_hash) &&
(lvar->allocated == TRUE) &&
(Text__compare_word_range(w1, w2, lvar->varname_w1, lvar->varname_w2)))
return lvar;
}
#line 456 "inform7/Chapter 22/Local Variables.w"
;
return NULL;
}
#line 480 "inform7/Chapter 22/Local Variables.w"
int stack_selection_used_recently = FALSE;
void Code__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 Code__LocalVariables__used_stack_selection(void) {
stack_selection_used_recently = TRUE;
}
int Code__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 512 "inform7/Chapter 22/Local Variables.w"
local_variable *Code__LocalVariables__it_variable(void) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf) return Code__LocalVariables__get_ith_parameter(0);
return add_to_locals_slate(NULL, TOKEN_CALL_PARAMETER_LV,
-1, -1, K_value, NULL, 0);
}
#line 522 "inform7/Chapter 22/Local Variables.w"
int Code__LocalVariables__is_possessive_form_of_it_enabled(void) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf) return phsf->local_value_variables.its_form_allowed;
return FALSE;
}
void Code__LocalVariables__enable_possessive_form_of_it(void) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf == NULL) internal_error("no stack frame exists");
phsf->local_value_variables.its_form_allowed = TRUE;
}
void Code__LocalVariables__Pronoun__add(ph_stack_frame *phsf, int cw1, int cw2, kind *K) {
phsf->local_value_variables.it_variable_exists = TRUE;
Code__LocalVariables__add_call_parameter(phsf, cw1, cw2, K);
}
void Code__LocalVariables__Pronoun__alias(ph_stack_frame *phsf, int ritw1, int ritw2) {
phsf->local_value_variables.it_pseudonym_w1 = ritw1;
phsf->local_value_variables.it_pseudonym_w2 = ritw2;
}
#line 551 "inform7/Chapter 22/Local Variables.w"
void Code__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++,
Code__LocalVariables__lvalue(lvar));
}
#line 564 "inform7/Chapter 22/Local Variables.w"
void Code__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",
Code__LocalVariables__lvalue(lvar),
j++);
}
#line 577 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__make_available_to_equation(equation *eqn) {
ph_stack_frame *phsf = Code__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)
Data__Equations__declare_local(eqn,
lvar->varname_w1, lvar->varname_w2, lvar->kind_as_declared);
}
}
#line 593 "inform7/Chapter 22/Local Variables.w"
local_variable *Code__LocalVariables__ensure_called_local(int w1, int w2, kind *K) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf == NULL) return NULL; /* in case callings are made from parsing alone */
parse_nt_against_word_range(new_called_name_NTM, w1, w2, NULL, NULL);
local_variable *lvar = most_recent_result_p;
if ((lvar) && (K)) Code__LocalVariables__set_kind(lvar, K);
return lvar;
}
#line 605 "inform7/Chapter 22/Local Variables.w"
int last_mnc_w1 = -1, last_mnc_w2 = -1;
void Code__LocalVariables__make_necessary_callings(int w1, int w2) {
if ((w1 >= last_mnc_w1) && (w2 <= last_mnc_w2)) return;
last_mnc_w1 = w1; last_mnc_w2 = w2;
while ((w1 <= w2) && (w1 >= 0)) {
if (parse_nt_against_word_range(text_including_a_calling_NTM, w1, w2, NULL, NULL)) {
int v1, v2;
GET_RW(text_including_a_calling_NTM, 2, v1, v2);
GET_RW(text_including_a_calling_NTM, 3, w1, w2);
Code__LocalVariables__ensure_called_local(v1, v2, K_object);
} else break;
}
}
#line 632 "inform7/Chapter 22/Local Variables.w"
int new_called_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 651 "inform7/Chapter 22/Local Variables.w"
*X = 0; *XP = NULL;
Problems__sentence_problem(_P_(C22CalledWithDash),
"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 633 "inform7/Chapter 22/Local Variables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = *X = R[2]; *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *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 636 "inform7/Chapter 22/Local Variables.w"
int new_called_name_unarticled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 659 "inform7/Chapter 22/Local Variables.w"
specification *already = most_recent_result_p;
if (Code__LocalVariables__permit_as_new_local(already, TRUE) == FALSE) {
LOG("Meaning already existing: $S\n", already);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
if (Specifications__Values__is_generic_CONSTANT(already))
Problems__quote_text(3, "a kind");
else
Problems__quote_kind_of(3, already);
Problems__handmade_problem(_P_(C22CalledOverloaded));
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 639 "inform7/Chapter 22/Local Variables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 680 "inform7/Chapter 22/Local Variables.w"
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
*X = 0;
*XP = (phsf)?(Code__LocalVariables__new(w1, w2, K_object)):NULL;
}
#line 640 "inform7/Chapter 22/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 641 "inform7/Chapter 22/Local Variables.w"
int existing_local_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 643 "inform7/Chapter 22/Local Variables.w"
*XP = Code__LocalVariables__parse(Code__Frames__current_stack_frame(), w1, w2);
if (*XP) return TRUE;
return FALSE;
}
#line 714 "inform7/Chapter 22/Local Variables.w"
int Code__LocalVariables__permit_as_new_local(specification *found, int as_calling) {
if ((Specifications__is_UNKNOWN(found)) ||
(Specifications__species_is(found, NONLOCAL_VARIABLE_SPC)) ||
(Specifications__species_is(found, DESCRIPTION_SPC)) ||
(Specifications__Values__is_CONSTANT_object(found)) ||
(Specifications__Values__get_named_constant_if_any(found)) ||
(Specifications__Values__is_CONSTANT_construction(found, CON_table_column)) ||
(Specifications__Values__is_CONSTANT_construction(found, CON_property))) return TRUE;
if (as_calling)
if (Specifications__is_phrasal(found)) return TRUE;
return FALSE;
}
#line 730 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__log(local_variable *lvar) {
if (lvar->allocated == FALSE) { LOG("LV<unallocated>"); return; }
if (lvar->varname_w1 >= 0) {
LOG("LV\"$W\"", lvar->varname_w1, lvar->varname_w2);
} else { LOG("LV<nameless>"); }
LOG("-$u", lvar->kind_as_declared);
}
#line 741 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__describe_repetition_local(OUTPUT_STREAM, local_variable *lvar) {
if ((lvar) && (lvar->lv_purpose == LET_VALUE_LV)) { /* should always be true */
WRITE("[repetition with ");
Text__print_raw_text_to_stream(lvar->varname_w1, lvar->varname_w2, OUT);
WRITE(" set to \", (%s) %s, \"]^\";\n",
Kinds__get_name_of_printing_rule(lvar->kind_as_declared),
Code__LocalVariables__lvalue(lvar));
}
}
#line 755 "inform7/Chapter 22/Local Variables.w"
kind *Code__LocalVariables__kind(local_variable *lvar) {
if (lvar == NULL) internal_error("Tried to find kind of nonexistent local variable");
return lvar->kind_as_declared;
}
kind *Code__LocalVariables__unproblematic_kind(local_variable *lvar) {
if (lvar) return Code__LocalVariables__kind(lvar);
return NULL;
}
#line 769 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__set_kind(local_variable *lvar, kind *K) {
if (lvar == NULL) internal_error("Tried to set kind of nonexistent local variable");
lvar->kind_as_declared = K;
}
#line 782 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__unprotect(local_variable *lvar) {
if (lvar->lv_purpose == LET_VALUE_LV)
lvar->protected = FALSE;
}
int Code__LocalVariables__protected(local_variable *lvar) {
if ((lvar->lv_purpose == LET_VALUE_LV) && (lvar->protected)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, lvar->varname_w1, lvar->varname_w2);
Problems__handmade_problem(_P_(C22ProtectedFromLet));
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 811 "inform7/Chapter 22/Local Variables.w"
void Code__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 821 "inform7/Chapter 22/Local Variables.w"
void Code__LocalVariables__end_scope(int s) {
ph_stack_frame *phsf = Code__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);
Code__LocalVariables__deallocate(lvar);
}
Specifications__warn_expression_cache();
}
#line 841 "inform7/Chapter 22/Local Variables.w"
local_variable *Code__LocalVariables__latest_repeat_variable(void) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf) {
int s = Code__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 867 "inform7/Chapter 22/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 Code__LocalVariables__begin_condition(OUTPUT_STREAM) {
current_session_number++;
WRITE("((");
}
void Code__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__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 Code__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 = ", Code__LocalVariables__lvalue(lvar));
kind *K = Code__LocalVariables__kind(lvar);
if ((K == NULL) || (Kinds__le(K, K_object)) ||
(Kinds__compile_default_value(OUT, K, -1, -1, "'called' value") != TRUE))
WRITE("0");
WRITE(",");
callings_in_condition_sp--;
}
if (any_made) WRITE("false)");
WRITE(")");
current_session_number--;
}
#line 916 "inform7/Chapter 22/Local Variables.w"
char *Code__LocalVariables__lvalue(local_variable *lvar) {
return lvar->lv_lvalue;
}
#line 924 "inform7/Chapter 22/Local Variables.w"
void Code__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", Code__LocalVariables__lvalue(lvar));
}
}
}
#line 940 "inform7/Chapter 22/Local Variables.w"
void Code__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", Code__LocalVariables__lvalue(lvar));
{
#line 962 "inform7/Chapter 22/Local Variables.w"
switch (purpose) {
case TOKEN_CALL_PARAMETER_LV:
if (lvar->varname_w1 >= 0) {
WRITE(" ! Call parameter '");
Text__print_raw_text_to_stream(lvar->varname_w1, lvar->varname_w2, OUT);
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, e.g., '");
Text__print_raw_text_to_stream(lvar->varname_w1, lvar->varname_w2, OUT);
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 951 "inform7/Chapter 22/Local Variables.w"
;
lines++;
}
}
if (lines > 0) WRITE("\n");
if (call_pars_only == FALSE) WRITE(";\n"); OUTDENT;
}
#line 52 "inform7/Chapter 22/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 60 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__empty_stack(void) {
current_block_stack.pb_sp = 0;
block_being_compiled = NULL;
block_being_opened = NULL;
}
#line 70 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__prepush_stack(void) {
block_being_opened = &(current_block_stack.pb_stack[current_block_stack.pb_sp]);
}
#line 77 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__push_stack(void) {
current_block_stack.pb_sp++;
block_being_compiled = block_being_opened;
block_being_opened = NULL;
}
#line 86 "inform7/Chapter 22/Phrase Blocks.w"
void Code__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 100 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__begin_code_blocks(void) {
if (Code__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");
Code__Frames__Blocks__empty_stack(); /* which it should be anyway */
LOGIF(LOCAL_VARIABLES, "Block stack now active\n");
}
#line 112 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__end_code_blocks(void) {
while (block_being_compiled) {
current_sentence = block_being_compiled->block_location;
Code__Frames__Blocks__pop_stack();
Problems__sentence_problem(_P_(C22BeginWithoutEnd),
"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'.");
}
block_being_compiled = NULL;
LOGIF(LOCAL_VARIABLES, "Block stack now inactive\n");
}
#line 139 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__beginning_block_phrase(OUTPUT_STREAM, phrase *ph) {
if (current_block_stack.pb_sp == MAX_BLOCK_NESTING) {
Problems__sentence_problem(_P_(C22BlockNestingTooDeep),
"compound phrases have gone too deep",
"perhaps because many have begun but not been properly ended?");
Code__Frames__Blocks__pop_stack();
}
Code__Frames__Blocks__prepush_stack();
{
#line 157 "inform7/Chapter 22/Phrase Blocks.w"
int i;
for (i=0; i<MAX_DIVISION_FORMS; i++)
block_being_opened->division_count[i] = 0;
block_being_opened->switch_kind = NULL;
block_being_opened->tail_stream = NULL;
block_being_opened->block_location = current_sentence;
block_being_opened->from_phrase = ph;
block_being_opened->label_following = -1;
}
#line 147 "inform7/Chapter 22/Phrase Blocks.w"
;
}
#line 170 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__open_code_block(OUTPUT_STREAM, phrase *owner, kind *K,
STREAM *TAIL) {
block_being_opened->switch_kind = K;
block_being_opened->tail_stream = TAIL;
WRITE("{");
if (current_block_stack.pb_sp != MAX_BLOCK_NESTING) Code__Frames__Blocks__push_stack();
LOGIF(LOCAL_VARIABLES, "Start of block level %d\n", current_block_stack.pb_sp);
}
#line 183 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__make_indentation_follow_code(OUTPUT_STREAM) {
int indent_level = current_block_stack.pb_sp + 1;
SET_INDENT(indent_level);
}
#line 199 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__divide_code_block(int division_form) {
if (block_being_compiled == NULL) return; /* for problem recovery only */
LOGIF(LOCAL_VARIABLES, "Division in block level %d\n", current_block_stack.pb_sp);
Code__LocalVariables__end_scope(current_block_stack.pb_sp);
block_being_compiled->division_count[division_form]++;
}
int Code__Frames__read_division_count(int division_form) {
if (block_being_compiled == NULL) return 0;
return block_being_compiled->division_count[division_form];
}
#line 214 "inform7/Chapter 22/Phrase Blocks.w"
void Code__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);
Code__LocalVariables__end_scope(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);
}
Code__Frames__Blocks__pop_stack();
}
#line 232 "inform7/Chapter 22/Phrase Blocks.w"
int Code__Frames__Blocks__inside_a_loop_body(void) {
int i;
for (i = current_block_stack.pb_sp-1; i >= 0; i--)
if (Code__Phrases__TypeData__block_follows(
current_block_stack.pb_stack[i].from_phrase)
== LOOP_BODY_BLOCK_FOLLOWS)
return TRUE;
return FALSE;
}
#line 245 "inform7/Chapter 22/Phrase Blocks.w"
int Code__Frames__Blocks__inside_a_conditional_block(void) {
int i;
for (i = current_block_stack.pb_sp-1; i >= 0; i--)
if (Code__Phrases__TypeData__block_follows(current_block_stack.pb_stack[i].from_phrase)
== CONDITIONAL_BLOCK_FOLLOWS)
return TRUE;
return FALSE;
}
#line 262 "inform7/Chapter 22/Phrase Blocks.w"
int Code__Frames__Blocks__current_block_level(void) {
return current_block_stack.pb_sp;
}
char *Code__Frames__Blocks__name_of_current_block(void) {
if (block_being_compiled == NULL) return NULL;
return Code__Phrases__TypeData__incipit(block_being_compiled->from_phrase);
}
parse_node *Code__Frames__Blocks__start_of_current_block(void) {
if (block_being_compiled == NULL) return NULL;
return block_being_compiled->block_location;
}
kind *Code__Frames__Blocks__switch_value_kind(void) {
if (block_being_compiled == NULL) return NULL;
return block_being_compiled->switch_kind;
}
#line 289 "inform7/Chapter 22/Phrase Blocks.w"
int unique_breakage_count = 0;
void Code__Frames__Blocks__compile_break(OUTPUT_STREAM) {
int i;
for (i = current_block_stack.pb_sp-1; i >= 0; i--)
if (Code__Phrases__TypeData__block_follows(
current_block_stack.pb_stack[i].from_phrase)
== LOOP_BODY_BLOCK_FOLLOWS) {
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 310 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__set_variable_scope(local_variable *lvar) {
if (Code__Frames__current_stack_frame())
Code__LocalVariables__set_scope_to(lvar,
current_block_stack.pb_sp);
}
#line 321 "inform7/Chapter 22/Phrase Blocks.w"
void Code__Frames__Blocks__set_scope_to_block_about_to_open(local_variable *lvar) {
if (Code__Frames__current_stack_frame())
Code__LocalVariables__set_scope_to(lvar,
current_block_stack.pb_sp + 1);
}
#line 67 "inform7/Chapter 22/Stack Frames.w"
ph_stack_frame Code__Frames__new(void) {
ph_stack_frame phsf;
phsf.local_value_variables = Code__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 22/Stack Frames.w"
int nonphrasal_stack_frame_is_current = FALSE;
ph_stack_frame nonphrasal_stack_frame;
ph_stack_frame *Code__Frames__new_nonphrasal(void) {
if (nonphrasal_stack_frame_is_current)
internal_error("can't nest nonphrasal stack frames");
nonphrasal_stack_frame = Code__Frames__new();
nonphrasal_stack_frame_is_current = TRUE;
Code__Frames__make_current(&nonphrasal_stack_frame);
return &nonphrasal_stack_frame;
}
void Code__Frames__remove_nonphrase_stack_frame(void) {
nonphrasal_stack_frame = Code__Frames__new(); /* to prevent accidental lucky misuse */
nonphrasal_stack_frame_is_current = FALSE;
Code__Frames__remove_current();
}
#line 105 "inform7/Chapter 22/Stack Frames.w"
ph_stack_frame *Code__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;
Code__LocalVariables__deep_copy_locals_slate(&(phsfb->boxed_phsf.local_value_variables),
&(phsf->local_value_variables));
return &(phsfb->boxed_phsf);
}
#line 121 "inform7/Chapter 22/Stack Frames.w"
ph_stack_frame *current_frame = NULL;
ph_stack_frame *Code__Frames__current_stack_frame(void) {
return current_frame;
}
void Code__Frames__make_current(ph_stack_frame *phsf) {
if (phsf == NULL) internal_error("can't select null stack frame");
current_frame = phsf;
}
void Code__Frames__remove_current(void) {
current_frame = NULL;
}
#line 140 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__set_kind_returned(ph_stack_frame *phsf, kind *K) {
phsf->kind_returned = K;
}
kind *Code__Frames__get_kind_returned(void) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf == NULL) return NULL;
return phsf->kind_returned;
}
#line 153 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__set_kind_variables(ph_stack_frame *phsf, kind **vars) {
phsf->local_kind_variables = vars;
}
kind *Code__Frames__get_kind_variable(int N) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if ((phsf) && (phsf->local_kind_variables))
return phsf->local_kind_variables[N];
return NULL;
}
kind **Code__Frames__temporarily_set_kvs(kind **vars) {
ph_stack_frame *phsf = Code__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 22/Stack Frames.w"
void Code__Frames__set_stvol(ph_stack_frame *phsf, stacked_variable_owner_list *stvol) {
phsf->local_stvol = stvol;
}
stacked_variable_owner_list *Code__Frames__get_stvol(void) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf) return phsf->local_stvol;
return NULL;
}
#line 190 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__determines_the_past(void) {
ph_stack_frame *phsf = Code__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 Code__Frames__used_for_past_tense(void) {
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
if (phsf == NULL) return FALSE;
if (phsf->determines_past_conditions) return TRUE;
return FALSE;
}
#line 208 "inform7/Chapter 22/Stack Frames.w"
void Code__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: ", Code__LocalVariables__lvalue(lvar));
Code__LocalVariables__log(lvar); LOG("\n");
}
}
#line 232 "inform7/Chapter 22/Stack Frames.w"
void Code__Frames__need_at_least_this_many_formals(int N) {
ph_stack_frame *phsf = Code__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 22/Stack Frames.w"
pointer_allocation *Code__Frames__add_allocation(kind *K, char *proto) {
ph_stack_frame *phsf = Code__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__get_small_block_size(K);
{
#line 278 "inform7/Chapter 22/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 22/Stack Frames.w"
;
{
#line 287 "inform7/Chapter 22/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 22/Stack Frames.w"
;
{
#line 303 "inform7/Chapter 22/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 22/Stack Frames.w"
;
return pall;
}
void Code__Frames__compile_allocation(OUTPUT_STREAM, kind *K) {
pointer_allocation *pall = Code__Frames__add_allocation(K, NULL);
WRITE("%s", Code__Frames__pall_get_local_reference(pall));
}
#line 321 "inform7/Chapter 22/Stack Frames.w"
char *Code__Frames__pall_get_local_reference(pointer_allocation *pall) {
return pall->local_reference_code;
}
char *Code__Frames__pall_get_expanded_schema(pointer_allocation *pall) {
return pall->schema_for_promotion;
}
#line 347 "inform7/Chapter 22/Stack Frames.w"
STREAM *Code__Routines__begin(OUTPUT_STREAM, char *name) {
return Code__Routines__begin_framed(OUT, name, NULL);
}
STREAM *Code__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 Code__Routines__begin_framed(OUT, rname, NULL);
}
#line 367 "inform7/Chapter 22/Stack Frames.w"
STREAM routine_body_stream_struct; STREAM *routine_body_stream = &routine_body_stream_struct;
#line 373 "inform7/Chapter 22/Stack Frames.w"
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 382 "inform7/Chapter 22/Stack Frames.w"
STREAM *Code__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) internal_error("bad compiled routine name");
strcpy(currently_compiling_identifier, name);
{
#line 403 "inform7/Chapter 22/Stack Frames.w"
if (phsf == NULL) {
phsf = Code__Frames__new_nonphrasal();
currently_compiling_nnp = TRUE;
} else {
currently_compiling_nnp = FALSE;
}
currently_compiling_in_frame = phsf;
Code__Frames__make_current(phsf);
}
#line 387 "inform7/Chapter 22/Stack Frames.w"
;
Code__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 415 "inform7/Chapter 22/Stack Frames.w"
STREAM *Code__Routines__end(OUTPUT_STREAM) {
return Code__Routines__end_retrieving(OUT, NULL);
}
STREAM *Code__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 459 "inform7/Chapter 22/Stack Frames.w"
if (Code__VirtualMachines__allow_this_many_locals(
Code__LocalVariables__count(currently_compiling_in_frame) + 1) == FALSE)
{
#line 561 "inform7/Chapter 22/Stack Frames.w"
Problems__sentence_problem(_P_(C22TooManyLocals),
"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 461 "inform7/Chapter 22/Stack Frames.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 473 "inform7/Chapter 22/Stack Frames.w"
int returns_block_value =
Kinds__uses_pointer_values(currently_compiling_in_frame->kind_returned);
WRITE("[ %s ", currently_compiling_identifier);
{
#line 494 "inform7/Chapter 22/Stack Frames.w"
if (returns_block_value) WRITE("I7RBLK ");
Code__LocalVariables__declare(OUT, currently_compiling_in_frame, TRUE);
if (!returns_block_value) WRITE("I7RBLK");
WRITE(";\n");
}
#line 477 "inform7/Chapter 22/Stack Frames.w"
;
INDENT;
int NBV = 0;
{
#line 502 "inform7/Chapter 22/Stack Frames.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 480 "inform7/Chapter 22/Stack Frames.w"
;
{
#line 518 "inform7/Chapter 22/Stack Frames.w"
WRITE("I7RBLK = ");
if (returns_block_value) WRITE("BlkValueCopy(I7RBLK, ");
WRITE("%s(", kernel_name);
Code__LocalVariables__compile_parameter_list(OUT, currently_compiling_in_frame, 0);
WRITE(")");
if (returns_block_value) WRITE(")");
WRITE(";\n");
}
#line 481 "inform7/Chapter 22/Stack Frames.w"
;
{
#line 531 "inform7/Chapter 22/Stack Frames.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 482 "inform7/Chapter 22/Stack Frames.w"
;
{
#line 543 "inform7/Chapter 22/Stack Frames.w"
WRITE("return I7RBLK; ! ");
Kinds__Textual__write(OUT, currently_compiling_in_frame->kind_returned);
WRITE("\n");
}
#line 483 "inform7/Chapter 22/Stack Frames.w"
;
OUTDENT; WRITE("];\n");
}
#line 467 "inform7/Chapter 22/Stack Frames.w"
;
{
#line 551 "inform7/Chapter 22/Stack Frames.w"
WRITE("[ %s ", kernel_name);
Code__LocalVariables__declare(OUT, currently_compiling_in_frame, FALSE);
WRITE(" ");
if (retrieve) Code__LocalVariables__compile_retrieval(OUT, retrieve);
STREAM_COPY(OUT, routine_body_stream);
WRITE("];\n");
}
#line 468 "inform7/Chapter 22/Stack Frames.w"
;
}
#line 427 "inform7/Chapter 22/Stack Frames.w"
else
{
#line 444 "inform7/Chapter 22/Stack Frames.w"
if (Code__VirtualMachines__allow_this_many_locals(
Code__LocalVariables__count(currently_compiling_in_frame)) == FALSE)
{
#line 561 "inform7/Chapter 22/Stack Frames.w"
Problems__sentence_problem(_P_(C22TooManyLocals),
"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 446 "inform7/Chapter 22/Stack Frames.w"
;
WRITE("[ ");
if (as_property == FALSE) WRITE("%s ", currently_compiling_identifier);
Code__LocalVariables__declare(OUT, currently_compiling_in_frame, FALSE);
WRITE(" ");
if (retrieve) Code__LocalVariables__compile_retrieval(OUT, retrieve);
STREAM_COPY(OUT, routine_body_stream);
WRITE("]");
if (as_property == FALSE) WRITE(";\n");
}
#line 429 "inform7/Chapter 22/Stack Frames.w"
;
STREAM_CLOSE(routine_body_stream); /* no longer needed */
Code__Frames__Blocks__end_code_blocks();
if (currently_compiling_nnp) Code__Frames__remove_nonphrase_stack_frame();
Code__Frames__remove_current();
Parser__SP__MeaningLists__finish_this_session();
return OUT;
}
#line 16 "inform7/Chapter 22/Parse Invocations.w"
int end_phrase_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 18 "inform7/Chapter 22/Parse Invocations.w"
#line 33 "inform7/Chapter 22/Parse Invocations.w"
void Code__Phrases__TypeData__register_excerpt(phrase *ph) {
ph_type_data *phtd = &(ph->type_data);
int w1 = phtd->register_w1, w2 = phtd->register_w2;
if (w1 < 0) return;
LOGIF(PHRASE_REGISTRATION, "Register phrase <$W> with type:\n$h", w1, w2, phtd);
switch(phtd->manner_of_return) {
case DECIDES_NOTHING_MOR:
if (Code__Phrases__TypeData__is_a_say_phrase(ph))
register_phrasal(SAY_PHRASE_MC, ph, w1+1, w2);
else
register_phrasal(VOID_PHRASE_MC, ph, w1, w2);
if (Code__Phrases__TypeData__block_follows(ph))
{
#line 56 "inform7/Chapter 22/Parse Invocations.w"
Semantics__Nouns__ExcerptMeanings__register_assemblage(END_PHRASE_MC, 0,
Text__Languages__merge(end_phrase_construction_NTM, 0,
Text__Words__from_range(w1, w1)),
STORE_POINTER_phrase(ph));
}
#line 45 "inform7/Chapter 22/Parse Invocations.w"
;
break;
case DECIDES_CONDITION_MOR: register_phrasal(COND_PHRASE_MC, ph, w1, w2); break;
case DECIDES_VALUE_MOR: register_phrasal(VALUE_PHRASE_MC, ph, w1, w2); break;
}
}
#line 65 "inform7/Chapter 22/Parse Invocations.w"
phrase *last_phrase_where_rp_problemed = NULL;
void register_phrasal(unsigned int phrase_mc, phrase *ph, int w1, int w2) {
LOGIF(PHRASE_REGISTRATION, "Register phrasal on <$W>: $u\n", w1, w2,
Code__Phrases__TypeData__kind(&(ph->type_data)));
{
#line 80 "inform7/Chapter 22/Parse Invocations.w"
int i, bl = 0, fixed_words = 0;
if (phrase_mc == SAY_PHRASE_MC) fixed_words++;
for (i=w1; i<=w2; i++) {
if (Text__word(i) == OPENBRACKET_V) bl++;
else if (Text__word(i) == CLOSEBRACKET_V) bl--;
else if (bl == 0) {
fixed_words++;
if (Text__Vocabulary__test_flags(i, TEXT_MC+TEXTWITHSUBS_MC))
{
#line 98 "inform7/Chapter 22/Parse Invocations.w"
if (ph != last_phrase_where_rp_problemed) {
Problems__sentence_problem(_P_(C22QuotedInPhrase),
"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 88 "inform7/Chapter 22/Parse Invocations.w"
;
}
if ((i<w2) && (Text__word(i) == CLOSEBRACKET_V) && (Text__word(i+1) == OPENBRACKET_V))
{
#line 109 "inform7/Chapter 22/Parse Invocations.w"
if (ph != last_phrase_where_rp_problemed) {
Problems__sentence_problem(_P_(C22AdjacentTokens),
"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 91 "inform7/Chapter 22/Parse Invocations.w"
;
}
if (fixed_words == 0)
{
#line 124 "inform7/Chapter 22/Parse Invocations.w"
if (ph != last_phrase_where_rp_problemed) {
Problems__sentence_problem(_P_(C22MustBeOneWord),
"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 93 "inform7/Chapter 22/Parse Invocations.w"
;
}
#line 70 "inform7/Chapter 22/Parse Invocations.w"
;
{
#line 140 "inform7/Chapter 22/Parse Invocations.w"
int i, bl = 0;
for (i=w1; i<=w2; i++) {
if (Text__word(i) == OPENBRACKET_V) bl++;
else if (Text__word(i) == CLOSEBRACKET_V) bl--;
else if (bl == 0) {
char *p = Text__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 172 "inform7/Chapter 22/Parse Invocations.w"
char a_form[MAX_WORD_LENGTH], b_form[MAX_WORD_LENGTH];
{
#line 185 "inform7/Chapter 22/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 173 "inform7/Chapter 22/Parse Invocations.w"
;
{
#line 199 "inform7/Chapter 22/Parse Invocations.w"
if ((strcmp(a_form, "say") == 0) && (i == w1) && (phrase_mc != SAY_PHRASE_MC))
if (ph != last_phrase_where_rp_problemed) {
Problems__sentence_problem(_P_(C22SaySlashed),
"'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 174 "inform7/Chapter 22/Parse Invocations.w"
;
int aw1, aw2, bw1, bw2;
{
#line 211 "inform7/Chapter 22/Parse Invocations.w"
aw1 = lexer_wordcount;
if (i > w1) Text__splice_words(w1, i-1);
if (a_form[0]) Text__feed_into_lexer(a_form, TRUE, NULL);
if (i < w2) Text__splice_words(i+1, w2);
aw2 = lexer_wordcount-1;
bw1 = lexer_wordcount;
if (i > w1) Text__splice_words(w1, i-1);
if (b_form[0]) Text__feed_into_lexer(b_form, TRUE, NULL);
if (i < w2) Text__splice_words(i+1, w2);
bw2 = lexer_wordcount-1;
}
#line 177 "inform7/Chapter 22/Parse Invocations.w"
;
if (aw1 <= aw2) register_phrasal(phrase_mc, ph, aw1, aw2);
if (bw1 <= bw2) register_phrasal(phrase_mc, ph, bw1, bw2);
return;
}
#line 150 "inform7/Chapter 22/Parse Invocations.w"
;
}
}
}
#line 71 "inform7/Chapter 22/Parse Invocations.w"
;
Semantics__Nouns__ExcerptMeanings__register(phrase_mc, 0, w1, w2,
STORE_POINTER_phrase(ph));
}
#line 253 "inform7/Chapter 22/Parse Invocations.w"
invocation *Code__Phrases__TypeData__parse_against(phrase *ph, meaning_list *ml) {
if (ml == NULL) internal_error("parse against null meaning list");
int whole_text_w1 = -1, whole_text_w2 = -1;
int options_w1 = -1, options_w2 = -1;
int token_text_w1[15], token_text_w2[15], no_tokens = 0;
{
#line 284 "inform7/Chapter 22/Parse Invocations.w"
Parser__SP__MeaningLists__get_text(ml, &whole_text_w1, &whole_text_w2);
ml = Parser__SP__MeaningLists__down(ml);
if (ml && (Parser__SP__MeaningLists__production(ml) == PHR_OPT_ML)) {
Parser__SP__MeaningLists__get_text(ml, &options_w1, &options_w2);
ml = Parser__SP__MeaningLists__right(ml);
}
for (; ((ml) && (no_tokens<15)); ml = Parser__SP__MeaningLists__right(ml)) {
if (Parser__SP__MeaningLists__production(ml) == UNPARSED_ML) {
Parser__SP__MeaningLists__get_text(ml,
&(token_text_w1[no_tokens]), &(token_text_w2[no_tokens]));
no_tokens++;
} else internal_error("Unexpected production in phrase args");
}
if (no_tokens > MAX_TOKENS_PER_PHRASE)
Problems__Fatal__issue("MAX_TOKENS_PER_PHRASE exceeded");
}
#line 258 "inform7/Chapter 22/Parse Invocations.w"
;
invocation *inv = Code__Invocations__new();
Code__Invocations__set_word_range(inv, whole_text_w1, whole_text_w2);
Code__Invocations__set_phrase_invoked(inv, ph);
if (no_tokens > 0) Code__Invocations__set_flag(inv, UNPROVEN_INVFLAG);
else Code__Invocations__clear_flag(inv, UNPROVEN_INVFLAG);
Plugins__Actions__Patterns__suspend_validation(FALSE);
ph_type_data *phtd = &(ph->type_data);
int i;
for (i=0; i<no_tokens; i++)
{
#line 305 "inform7/Chapter 22/Parse Invocations.w"
specification *to_match = phtd->token_sequence[i].to_match;
int x1 = token_text_w1[i], x2 = token_text_w2[i];
Text__Languages__remove_the(&x1, &x2);
Code__Invocations__set_token_to_be_parsed_against(inv, i, to_match);
specification *as_parsed = Specifications__Unknown__new(x1, x2);
as_parsed->word_ref1 = x1; as_parsed->word_ref2 = x2;
Code__Invocations__set_token_as_parsed(inv, i, as_parsed);
}
#line 270 "inform7/Chapter 22/Parse Invocations.w"
;
if (options_w1 >= 0)
Code__Invocations__set_phrase_options(inv, options_w1, options_w2);
Plugins__Actions__Patterns__suspend_validation(FALSE);
LOGIF(MATCHING, "Parse against to invocation: $e\n", inv);
return inv;
}
#line 318 "inform7/Chapter 22/Parse Invocations.w"
void Code__Phrases__TypeData__parse_within_inv(invocation *inv) {
Specifications__warn_expression_cache();
int N = Code__Invocations__get_no_tokens(inv);
for (int i = 0; i < N; i++) {
specification *to_match = Code__Invocations__get_token_to_be_parsed_against(inv, i);
if (to_match) {
specification *as_parsed = Code__Invocations__get_token_as_parsed(inv, i);
int x1 = as_parsed->word_ref1, x2 = as_parsed->word_ref2;
int pto = permit_trying_omission;
int save_lppwi = last_parsed_phrase_was_if;
last_parsed_phrase_was_if = FALSE;
if (Specifications__species_is(to_match, TRY_ACTION_SPC)) {
permit_trying_omission = TRUE;
{
#line 347 "inform7/Chapter 22/Parse Invocations.w"
if (parse_nt_against_word_range(action_pattern_NTM, x1, x2, NULL, NULL))
as_parsed = Specifications__Conditions__new_TEST_ACTION(most_recent_result_p);
else
as_parsed = Specifications__Unknown__new(x1, x2);
}
#line 331 "inform7/Chapter 22/Parse Invocations.w"
;
} else {
permit_trying_omission = FALSE;
{
#line 355 "inform7/Chapter 22/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__Values__is_generic_CONSTANT(to_match))
probable_noun_phrase_context =
Specifications__Values__kind_when_VALUE_is_evaluated(to_match);
phrase *ph = Code__Invocations__get_phrase_invoked(inv);
let_equation_mode = Code__Phrases__TypeData__is_a_let_equation(ph);
int t = FALSE; /* redundant assignment to keep |gcc| happy */
if (Specifications__species_is(to_match, DESCRIPTION_SPC))
t = parse_nt_against_word_range(spec_value_NTM, x1, x2, NULL, NULL);
else if (Specifications__family_is(to_match, CONDITION_FMY))
t = parse_nt_against_word_range(spec_condition_NTM, x1, x2, NULL, NULL);
else if (Specifications__family_is(to_match, COMMAND_FMY))
t = parse_nt_against_word_range(spec_command_NTM, x1, x2, NULL, NULL);
else
t = parse_nt_against_word_range(spec_value_NTM, x1, x2, NULL, NULL);
if (t) as_parsed = most_recent_result_p;
else as_parsed = Specifications__Unknown__new(x1, x2);
LOGIF(MATCHING, "(%d/%d) Expected kind $u: parsed token to $S\n", i+1, N, probable_noun_phrase_context, as_parsed);
probable_noun_phrase_context = save_probable_noun_phrase_context;
let_equation_mode = save_let_equation_mode;
}
#line 334 "inform7/Chapter 22/Parse Invocations.w"
;
}
permit_trying_omission = pto;
as_parsed->word_ref1 = x1; as_parsed->word_ref2 = x2;
Code__Invocations__set_token_as_parsed(inv, i, as_parsed);
last_parsed_phrase_was_if = save_lppwi;
}
}
}
#line 47 "inform7/Chapter 22/Compile Invocations.w"
void Code__Invocations__Compiler__compile(OUTPUT_STREAM, invocation_list *invl, int wn) {
int inv_count = 0, group_count = -1;
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_INVOCATION_LIST(inv, invl) {
if (Code__Invocations__get_group(inv) > group_count) {
invocation_group invg;
{
#line 64 "inform7/Chapter 22/Compile Invocations.w"
invg.invl_in_question = invl;
invg.first_inv = inv;
invg.first_pos = inv_count;
invg.first_in_next_group = NULL;
invg.say_like = FALSE;
if ((inv->say_verb) || (inv->say_adjective) ||
(Code__Phrases__TypeData__is_a_say_phrase(inv->phrase_invoked)))
invg.say_like = TRUE;
int pos = inv_count;
INVOCATION_VARIABLE(lookahead);
LOOK_AHEAD_THROUGH_INVOCATION_LIST(lookahead, inv, invl) {
if (Code__Invocations__get_group(lookahead) != Code__Invocations__get_group(inv)) {
invg.first_in_next_group = lookahead; break;
}
invg.last_inv = lookahead;
invg.last_pos = pos++;
}
}
#line 53 "inform7/Chapter 22/Compile Invocations.w"
;
compile_invocation_block(OUT, &invg, wn);
group_count = Code__Invocations__get_group(inv);
}
inv_count++;
}
}
#line 104 "inform7/Chapter 22/Compile Invocations.w"
void compile_invocation_block(OUTPUT_STREAM, invocation_group *invg, int wn) {
{
#line 127 "inform7/Chapter 22/Compile Invocations.w"
STREAM_MUST_BE_IN_MEMORY(OUT);
if ((invg->first_pos<0) || (invg->last_pos<0) || (invg->last_pos < invg->first_pos))
internal_error("Bad positions in compile invocation block range");
if ((invg->first_inv == NULL) || (invg->last_inv == NULL))
internal_error("Bad invs in compile invocation block range");
LOGIF(MATCHING,
"Compiling invocation group %d (C%d to C%d) (%s)\n",
Code__Invocations__get_group(invg->first_inv), invg->first_pos, invg->last_pos,
(invg->first_in_next_group == NULL)?"final":"intermediate");
}
#line 105 "inform7/Chapter 22/Compile Invocations.w"
;
source_location sl = Text__word_location(wn);
if (Code__Invocations__test_flag(invg->first_inv, SAVE_SELF_INVFLAG))
WRITE("@push self; ");
if (invg->say_like) Code__SayPhrases__compile_invocation_group(OUT, invg, -1);
if (Code__Invocations__test_flag(invg->first_inv, UNPROVEN_INVFLAG))
{
#line 234 "inform7/Chapter 22/Compile Invocations.w"
phrase *ph = invg->first_inv->phrase_invoked;
int N = Code__Invocations__get_number_tokens(invg->first_inv);
Code__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 336 "inform7/Chapter 22/Compile Invocations.w"
if (void_mode) {
{
#line 374 "inform7/Chapter 22/Compile Invocations.w"
if (void_mode) {
int i;
for (i=0; i<N; i++) {
{
#line 392 "inform7/Chapter 22/Compile Invocations.w"
nonlocal_variable *nlv = Data__NonlocalVariables__temporary_formal(i);
WRITE("%s = ", Data__NonlocalVariables__lvalue_identifier(nlv));
if (ph->type_data.token_sequence[i].name_of_a_kind)
WRITE("0");
else {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
specification *value =
Code__Invocations__get_token_as_parsed(invg->first_inv, i);
kind *to_be_used_as = Specifications__get_kind_referred_to(
ph->type_data.token_sequence[i].to_match);
Specifications__compile_to_kind(OUT, value, to_be_used_as);
END_COMPILATION_MODE;
}
}
#line 377 "inform7/Chapter 22/Compile Invocations.w"
; WRITE(";\n");
}
} else {
int i;
for (i=N-1; i>=0; i--) {
WRITE("(");
{
#line 392 "inform7/Chapter 22/Compile Invocations.w"
nonlocal_variable *nlv = Data__NonlocalVariables__temporary_formal(i);
WRITE("%s = ", Data__NonlocalVariables__lvalue_identifier(nlv));
if (ph->type_data.token_sequence[i].name_of_a_kind)
WRITE("0");
else {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
specification *value =
Code__Invocations__get_token_as_parsed(invg->first_inv, i);
kind *to_be_used_as = Specifications__get_kind_referred_to(
ph->type_data.token_sequence[i].to_match);
Specifications__compile_to_kind(OUT, value, to_be_used_as);
END_COMPILATION_MODE;
}
}
#line 382 "inform7/Chapter 22/Compile Invocations.w"
; WRITE(")");
if (i>0) WRITE(" +");
WRITE("\n");
}
}
}
#line 337 "inform7/Chapter 22/Compile Invocations.w"
;
{
#line 431 "inform7/Chapter 22/Compile Invocations.w"
int no_conditions_tested = 0;
int pos;
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_PART_OF_INVOCATION_LIST(inv, invg->invl_in_question, pos,
invg->first_pos, invg->last_pos - invg->first_pos + 1) {
LOGIF(MATCHING, "RC%d: $e\n", pos, inv);
if (no_conditions_tested > 0) {
if (void_mode) WRITE("else ");
else WRITE("|| ");
}
if (!void_mode) WRITE("(");
{
#line 463 "inform7/Chapter 22/Compile Invocations.w"
if (inv->say_verb)
Semantics__ConjugateVerb_invoke(OUT, inv->say_verb, inv->modal_verb, inv->say_verb_negated);
else if (inv->say_adjective)
Semantics__Adjectives__Meanings__invoke(OUT, inv->say_adjective);
else {
phrase *ph = inv->phrase_invoked;
tokens_packet tokens;
int brace_this = FALSE;
{
#line 169 "inform7/Chapter 22/Compile Invocations.w"
tokens.tokens_count = Code__Invocations__get_number_tokens(inv);
int i;
for (i=0; i<tokens.tokens_count; i++) {
specification *val = Code__Invocations__get_token_as_parsed(inv, i);
kind *K = Specifications__get_kind_referred_to(
ph->type_data.token_sequence[i].to_match);
if ((Code__Phrases__TypeData__invoked_inline(ph) == FALSE) &&
(Kinds__definite(K) == FALSE))
tokens.kind_required[i] = Specifications__get_kind_referred_to(val);
else
tokens.kind_required[i] = K;
if (ph->type_data.token_sequence[i].name_of_a_kind)
tokens.args[i] = Specifications__Values__new_nothing_object_constant();
else
tokens.args[i] = val;
}
kind *return_kind = invg->first_inv->kind_resulting;
if (return_kind == NULL) return_kind = ph->type_data.return_kind;
tokens.as_requested =
Kinds__function_kind(tokens.tokens_count, tokens.kind_required, return_kind);
}
#line 471 "inform7/Chapter 22/Compile Invocations.w"
;
{
#line 482 "inform7/Chapter 22/Compile Invocations.w"
int i;
for (i=0; i<tokens.tokens_count; i++) {
nonlocal_variable *nlv = Data__NonlocalVariables__temporary_formal(i);
Data__NonlocalVariables__set_kind(nlv, tokens.kind_required[i]
/* Specifications__get_kind_referred_to(
ph->type_data.token_sequence[i].to_match) */);
tokens.args[i] =
Specifications__Storage__new_actual_NONLOCAL_VARIABLE(nlv);
}
}
#line 472 "inform7/Chapter 22/Compile Invocations.w"
;
{
#line 495 "inform7/Chapter 22/Compile Invocations.w"
TEMPORARY_STREAM;
{
#line 512 "inform7/Chapter 22/Compile Invocations.w"
int i, condition_attached = FALSE;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
for (i=0; i<Code__Invocations__get_number_tokens(inv); i++) {
specification *check_against = Code__Invocations__get_token_check_to_do(inv, i);
if (check_against != NULL) {
if (condition_attached == FALSE) STREAM_WRITE(TEMP, "(");
else STREAM_WRITE(TEMP, " && ");
condition_attached = TRUE;
nonlocal_variable *nlv = Data__NonlocalVariables__temporary_formal(i);
specification *spec = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(nlv);
{
#line 547 "inform7/Chapter 22/Compile Invocations.w"
if (Specifications__species_is(check_against, DESCRIPTION_SPC)) {
STREAM_WRITE(TEMP, "(");
Calculus__Deferrals__compile_test_if_var_matches_description(TEMP,
spec, check_against);
STREAM_WRITE(TEMP, ")");
} else if ((Specifications__is_evaluating(check_against)) &&
(Specifications__is_actual(check_against))) {
pcalc_prop *prop = Calculus__Propositions__to_set_relation(R_equality,
NULL, spec, NULL, check_against);
Calculus__Deferrals__compile_test_of_proposition(TEMP, NULL, prop);
} else {
LOG("Error on: $X", check_against);
internal_error("bad check-against in run-time type check");
}
}
#line 526 "inform7/Chapter 22/Compile Invocations.w"
;
}
}
if (condition_attached) STREAM_WRITE(TEMP, ")");
END_COMPILATION_MODE;
}
#line 496 "inform7/Chapter 22/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 (Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG))
internal_error("unable to compile a run-time kind check");
CLOSE_TEMPORARY_STREAM;
}
#line 473 "inform7/Chapter 22/Compile Invocations.w"
;
if (brace_this) WRITE(" { ");
{
#line 574 "inform7/Chapter 22/Compile Invocations.w"
if (!void_mode) WRITE("((\nformal_rv = ");
int returned_in_manner =
compile_single_invocation(OUT, inv, &sl, &tokens);
if (!void_mode) { WRITE(") | 1)\n"); }
if (returned_in_manner != UNKNOWN)
{
#line 197 "inform7/Chapter 22/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,
Code__Phrases__TypeData__describe_manner_of_return(returned_in_manner, NULL, NULL));
kind *K = NULL;
Problems__quote_text(3,
Code__Phrases__TypeData__describe_manner_of_return(manner_expected,
&(phrase_being_compiled->type_data), &K));
if (K) Problems__quote_kind(4, K);
Problems__handmade_problem(_P_(C22WrongEndToPhrase));
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 579 "inform7/Chapter 22/Compile Invocations.w"
;
}
#line 475 "inform7/Chapter 22/Compile Invocations.w"
;
if (brace_this) WRITE(" }\n");
}
}
#line 442 "inform7/Chapter 22/Compile Invocations.w"
;
if (!void_mode) WRITE(")");
}
if (Code__Invocations__test_flag(invg->last_inv, UNPROVEN_INVFLAG))
{
#line 451 "inform7/Chapter 22/Compile Invocations.w"
if (no_conditions_tested == 0) internal_error("condition proof error");
if (void_mode) WRITE("else ");
else WRITE("|| (");
extension_file *ef = Text__Reader__sf_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 446 "inform7/Chapter 22/Compile Invocations.w"
;
}
#line 338 "inform7/Chapter 22/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 431 "inform7/Chapter 22/Compile Invocations.w"
int no_conditions_tested = 0;
int pos;
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_PART_OF_INVOCATION_LIST(inv, invg->invl_in_question, pos,
invg->first_pos, invg->last_pos - invg->first_pos + 1) {
LOGIF(MATCHING, "RC%d: $e\n", pos, inv);
if (no_conditions_tested > 0) {
if (void_mode) WRITE("else ");
else WRITE("|| ");
}
if (!void_mode) WRITE("(");
{
#line 463 "inform7/Chapter 22/Compile Invocations.w"
if (inv->say_verb)
Semantics__ConjugateVerb_invoke(OUT, inv->say_verb, inv->modal_verb, inv->say_verb_negated);
else if (inv->say_adjective)
Semantics__Adjectives__Meanings__invoke(OUT, inv->say_adjective);
else {
phrase *ph = inv->phrase_invoked;
tokens_packet tokens;
int brace_this = FALSE;
{
#line 169 "inform7/Chapter 22/Compile Invocations.w"
tokens.tokens_count = Code__Invocations__get_number_tokens(inv);
int i;
for (i=0; i<tokens.tokens_count; i++) {
specification *val = Code__Invocations__get_token_as_parsed(inv, i);
kind *K = Specifications__get_kind_referred_to(
ph->type_data.token_sequence[i].to_match);
if ((Code__Phrases__TypeData__invoked_inline(ph) == FALSE) &&
(Kinds__definite(K) == FALSE))
tokens.kind_required[i] = Specifications__get_kind_referred_to(val);
else
tokens.kind_required[i] = K;
if (ph->type_data.token_sequence[i].name_of_a_kind)
tokens.args[i] = Specifications__Values__new_nothing_object_constant();
else
tokens.args[i] = val;
}
kind *return_kind = invg->first_inv->kind_resulting;
if (return_kind == NULL) return_kind = ph->type_data.return_kind;
tokens.as_requested =
Kinds__function_kind(tokens.tokens_count, tokens.kind_required, return_kind);
}
#line 471 "inform7/Chapter 22/Compile Invocations.w"
;
{
#line 482 "inform7/Chapter 22/Compile Invocations.w"
int i;
for (i=0; i<tokens.tokens_count; i++) {
nonlocal_variable *nlv = Data__NonlocalVariables__temporary_formal(i);
Data__NonlocalVariables__set_kind(nlv, tokens.kind_required[i]
/* Specifications__get_kind_referred_to(
ph->type_data.token_sequence[i].to_match) */);
tokens.args[i] =
Specifications__Storage__new_actual_NONLOCAL_VARIABLE(nlv);
}
}
#line 472 "inform7/Chapter 22/Compile Invocations.w"
;
{
#line 495 "inform7/Chapter 22/Compile Invocations.w"
TEMPORARY_STREAM;
{
#line 512 "inform7/Chapter 22/Compile Invocations.w"
int i, condition_attached = FALSE;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
for (i=0; i<Code__Invocations__get_number_tokens(inv); i++) {
specification *check_against = Code__Invocations__get_token_check_to_do(inv, i);
if (check_against != NULL) {
if (condition_attached == FALSE) STREAM_WRITE(TEMP, "(");
else STREAM_WRITE(TEMP, " && ");
condition_attached = TRUE;
nonlocal_variable *nlv = Data__NonlocalVariables__temporary_formal(i);
specification *spec = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(nlv);
{
#line 547 "inform7/Chapter 22/Compile Invocations.w"
if (Specifications__species_is(check_against, DESCRIPTION_SPC)) {
STREAM_WRITE(TEMP, "(");
Calculus__Deferrals__compile_test_if_var_matches_description(TEMP,
spec, check_against);
STREAM_WRITE(TEMP, ")");
} else if ((Specifications__is_evaluating(check_against)) &&
(Specifications__is_actual(check_against))) {
pcalc_prop *prop = Calculus__Propositions__to_set_relation(R_equality,
NULL, spec, NULL, check_against);
Calculus__Deferrals__compile_test_of_proposition(TEMP, NULL, prop);
} else {
LOG("Error on: $X", check_against);
internal_error("bad check-against in run-time type check");
}
}
#line 526 "inform7/Chapter 22/Compile Invocations.w"
;
}
}
if (condition_attached) STREAM_WRITE(TEMP, ")");
END_COMPILATION_MODE;
}
#line 496 "inform7/Chapter 22/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 (Code__Invocations__test_flag(inv, UNPROVEN_INVFLAG))
internal_error("unable to compile a run-time kind check");
CLOSE_TEMPORARY_STREAM;
}
#line 473 "inform7/Chapter 22/Compile Invocations.w"
;
if (brace_this) WRITE(" { ");
{
#line 574 "inform7/Chapter 22/Compile Invocations.w"
if (!void_mode) WRITE("((\nformal_rv = ");
int returned_in_manner =
compile_single_invocation(OUT, inv, &sl, &tokens);
if (!void_mode) { WRITE(") | 1)\n"); }
if (returned_in_manner != UNKNOWN)
{
#line 197 "inform7/Chapter 22/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,
Code__Phrases__TypeData__describe_manner_of_return(returned_in_manner, NULL, NULL));
kind *K = NULL;
Problems__quote_text(3,
Code__Phrases__TypeData__describe_manner_of_return(manner_expected,
&(phrase_being_compiled->type_data), &K));
if (K) Problems__quote_kind(4, K);
Problems__handmade_problem(_P_(C22WrongEndToPhrase));
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 579 "inform7/Chapter 22/Compile Invocations.w"
;
}
#line 475 "inform7/Chapter 22/Compile Invocations.w"
;
if (brace_this) WRITE(" }\n");
}
}
#line 442 "inform7/Chapter 22/Compile Invocations.w"
;
if (!void_mode) WRITE(")");
}
if (Code__Invocations__test_flag(invg->last_inv, UNPROVEN_INVFLAG))
{
#line 451 "inform7/Chapter 22/Compile Invocations.w"
if (no_conditions_tested == 0) internal_error("condition proof error");
if (void_mode) WRITE("else ");
else WRITE("|| (");
extension_file *ef = Text__Reader__sf_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 446 "inform7/Chapter 22/Compile Invocations.w"
;
}
#line 347 "inform7/Chapter 22/Compile Invocations.w"
;
OUTDENT; WRITE("\n))\n");
OUTDENT; WRITE("+\n"); INDENT;
WRITE("! The following assignments evaluate first\n");
WRITE("(");
{
#line 374 "inform7/Chapter 22/Compile Invocations.w"
if (void_mode) {
int i;
for (i=0; i<N; i++) {
{
#line 392 "inform7/Chapter 22/Compile Invocations.w"
nonlocal_variable *nlv = Data__NonlocalVariables__temporary_formal(i);
WRITE("%s = ", Data__NonlocalVariables__lvalue_identifier(nlv));
if (ph->type_data.token_sequence[i].name_of_a_kind)
WRITE("0");
else {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
specification *value =
Code__Invocations__get_token_as_parsed(invg->first_inv, i);
kind *to_be_used_as = Specifications__get_kind_referred_to(
ph->type_data.token_sequence[i].to_match);
Specifications__compile_to_kind(OUT, value, to_be_used_as);
END_COMPILATION_MODE;
}
}
#line 377 "inform7/Chapter 22/Compile Invocations.w"
; WRITE(";\n");
}
} else {
int i;
for (i=N-1; i>=0; i--) {
WRITE("(");
{
#line 392 "inform7/Chapter 22/Compile Invocations.w"
nonlocal_variable *nlv = Data__NonlocalVariables__temporary_formal(i);
WRITE("%s = ", Data__NonlocalVariables__lvalue_identifier(nlv));
if (ph->type_data.token_sequence[i].name_of_a_kind)
WRITE("0");
else {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
specification *value =
Code__Invocations__get_token_as_parsed(invg->first_inv, i);
kind *to_be_used_as = Specifications__get_kind_referred_to(
ph->type_data.token_sequence[i].to_match);
Specifications__compile_to_kind(OUT, value, to_be_used_as);
END_COMPILATION_MODE;
}
}
#line 382 "inform7/Chapter 22/Compile Invocations.w"
; WRITE(")");
if (i>0) WRITE(" +");
WRITE("\n");
}
}
}
#line 352 "inform7/Chapter 22/Compile Invocations.w"
;
WRITE(")");
OUTDENT; WRITE(")\n");
OUTDENT; WRITE(")\n");
}
}
#line 244 "inform7/Chapter 22/Compile Invocations.w"
;
OUTDENT; WRITE("\n! Resolution complete\n");
}
#line 114 "inform7/Chapter 22/Compile Invocations.w"
else
{
#line 142 "inform7/Chapter 22/Compile Invocations.w"
int pos;
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_PART_OF_INVOCATION_LIST(inv, invg->invl_in_question, pos,
invg->first_pos, invg->last_pos - invg->first_pos + 1) {
LOGIF(MATCHING, "C%d: $e\n", pos, inv);
if (inv->say_verb)
Semantics__ConjugateVerb_invoke(OUT, inv->say_verb, inv->modal_verb, inv->say_verb_negated);
else if (inv->say_adjective)
Semantics__Adjectives__Meanings__invoke(OUT, inv->say_adjective);
else
{
#line 158 "inform7/Chapter 22/Compile Invocations.w"
phrase *ph = inv->phrase_invoked;
tokens_packet tokens;
{
#line 169 "inform7/Chapter 22/Compile Invocations.w"
tokens.tokens_count = Code__Invocations__get_number_tokens(inv);
int i;
for (i=0; i<tokens.tokens_count; i++) {
specification *val = Code__Invocations__get_token_as_parsed(inv, i);
kind *K = Specifications__get_kind_referred_to(
ph->type_data.token_sequence[i].to_match);
if ((Code__Phrases__TypeData__invoked_inline(ph) == FALSE) &&
(Kinds__definite(K) == FALSE))
tokens.kind_required[i] = Specifications__get_kind_referred_to(val);
else
tokens.kind_required[i] = K;
if (ph->type_data.token_sequence[i].name_of_a_kind)
tokens.args[i] = Specifications__Values__new_nothing_object_constant();
else
tokens.args[i] = val;
}
kind *return_kind = invg->first_inv->kind_resulting;
if (return_kind == NULL) return_kind = ph->type_data.return_kind;
tokens.as_requested =
Kinds__function_kind(tokens.tokens_count, tokens.kind_required, return_kind);
}
#line 160 "inform7/Chapter 22/Compile Invocations.w"
;
int returned_in_manner =
compile_single_invocation(OUT, inv, &sl, &tokens);
if ((phrase_being_compiled) && (returned_in_manner != UNKNOWN))
{
#line 197 "inform7/Chapter 22/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,
Code__Phrases__TypeData__describe_manner_of_return(returned_in_manner, NULL, NULL));
kind *K = NULL;
Problems__quote_text(3,
Code__Phrases__TypeData__describe_manner_of_return(manner_expected,
&(phrase_being_compiled->type_data), &K));
if (K) Problems__quote_kind(4, K);
Problems__handmade_problem(_P_(C22WrongEndToPhrase));
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 164 "inform7/Chapter 22/Compile Invocations.w"
;
}
#line 152 "inform7/Chapter 22/Compile Invocations.w"
;
}
}
#line 116 "inform7/Chapter 22/Compile Invocations.w"
;
if (invg->say_like) Code__SayPhrases__compile_invocation_group(OUT, invg, 1);
if (Code__Invocations__test_flag(invg->first_inv, SAVE_SELF_INVFLAG))
WRITE("@pull self; ");
}
#line 587 "inform7/Chapter 22/Compile Invocations.w"
int compile_single_invocation(OUTPUT_STREAM, invocation *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 = inv->phrase_invoked;
int append_close_brace = FALSE;
int manner_of_return = UNKNOWN;
if (ph->type_data.manner_of_return == DECIDES_CONDITION_MOR) WRITE("(");
{
#line 621 "inform7/Chapter 22/Compile Invocations.w"
if (Code__Phrases__TypeData__invoked_inline(ph))
manner_of_return =
Code__Invocations__Compiler__csi_inline(OUT, inv, where_from, tokens,
&append_close_brace);
else
Code__Invocations__Compiler__csi_by_call(OUT, inv, where_from, tokens);
}
#line 599 "inform7/Chapter 22/Compile Invocations.w"
;
if (ph->type_data.manner_of_return == DECIDES_CONDITION_MOR) WRITE(")");
{
#line 632 "inform7/Chapter 22/Compile Invocations.w"
if ((Code__Invocations__implies_newline(inv)) &&
(tokens->tokens_count > 0) &&
(Specifications__Values__is_CONSTANT_of_kind(tokens->args[0], K_text)) &&
(Text__text_ending_sentence(tokens->args[0]->word_ref1)))
WRITE(" new_line;");
}
#line 602 "inform7/Chapter 22/Compile Invocations.w"
;
{
#line 641 "inform7/Chapter 22/Compile Invocations.w"
if (Code__Invocations__test_flag(inv, INSTEAD_INVFLAG)) {
WRITE(" rtrue;");
manner_of_return = DECIDES_NOTHING_AND_RETURNS_MOR;
}
}
#line 603 "inform7/Chapter 22/Compile Invocations.w"
;
if (append_close_brace) WRITE(" }");
END_COMPILATION_MODE;
if (manner_of_return != UNKNOWN)
LOGIF(MATCHING, "Single invocation return manner: %d\n", manner_of_return);
return manner_of_return;
}
#line 11 "inform7/Chapter 22/Compile Invocations As Calls.w"
void Code__Invocations__Compiler__csi_by_call(OUTPUT_STREAM, invocation *inv,
source_location *where_from, tokens_packet *tokens) {
phrase *ph = inv->phrase_invoked;
if (Code__Phrases__TypeData__block_follows(ph))
{
#line 35 "inform7/Chapter 22/Compile Invocations As Calls.w"
Problems__sentence_problem(_P_(C22NonInlineBeginEnd),
"the 'phrase' token can only be used in definitions given in terms of "
"inline Inform 6 using (- and -)",
"and really is only for the use of the Standard Rules.");
}
#line 15 "inform7/Chapter 22/Compile Invocations As Calls.w"
;
char identifier[32];
Code__Routines__compile_identifier(identifier, ph,
Code__Routines__ToPhrases__Requests__make(ph, tokens->as_requested,
inv->kind_variable_declarations, inv->invocation_w1, inv->invocation_w2));
LOGIF(MATCHING, "Calling routine %s with kind $u from $e\n", identifier,
tokens->as_requested, inv);
int options_supplied = Code__Invocations__get_phrase_options_bitmap(inv);
if (inv->phrase_options_invoked == NULL) options_supplied = -1;
compile_function_call(OUT, tokens, identifier, options_supplied);
if (ph->type_data.manner_of_return == DECIDES_NOTHING_MOR) WRITE(";");
}
#line 45 "inform7/Chapter 22/Compile Invocations As Calls.w"
void compile_function_call(OUTPUT_STREAM,
tokens_packet *tokens, char *identifier, int phrase_options) {
kind *return_kind = NULL;
{
#line 87 "inform7/Chapter 22/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 49 "inform7/Chapter 22/Compile Invocations As Calls.w"
;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
WRITE("(");
WRITE("%s", identifier);
WRITE("(");
{
#line 69 "inform7/Chapter 22/Compile Invocations As Calls.w"
int count = 0;
if (Kinds__uses_pointer_values(return_kind)) {
Code__Frames__compile_allocation(OUT, return_kind);
count = 1;
}
int k;
for (k=0; k<tokens->tokens_count; k++) {
if (count++ > 0) WRITE(",");
Specifications__compile_to_kind(OUT, tokens->args[k], tokens->kind_required[k]);
}
if (phrase_options != -1) {
if (count++ > 0) WRITE(",");
WRITE("%d", phrase_options);
}
}
#line 57 "inform7/Chapter 22/Compile Invocations As Calls.w"
;
WRITE("))");
END_COMPILATION_MODE;
}
#line 34 "inform7/Chapter 22/Compile Invocations Inline.w"
int Code__Invocations__Compiler__csi_inline(OUTPUT_STREAM,
invocation *inv, source_location *where_from, tokens_packet *tokens,
int *append_close_brace) {
phrase *ph = inv->phrase_invoked;
local_variable *my_vars[10]; /* the "my" variables 0 to 9 */
{
#line 66 "inform7/Chapter 22/Compile Invocations Inline.w"
int i; for (i=0; i<10; i++) my_vars[i] = NULL;
}
#line 41 "inform7/Chapter 22/Compile Invocations Inline.w"
;
{
#line 77 "inform7/Chapter 22/Compile Invocations Inline.w"
int i;
for (i=0; i<Code__Invocations__get_number_tokens(inv); i++) {
specification *val = tokens->args[i];
kind *K = Code__Invocations__get_token_variable_kind(inv, i);
if (K)
{
#line 87 "inform7/Chapter 22/Compile Invocations Inline.w"
local_variable *lvar = Code__LocalVariables__new(val->word_ref1, val->word_ref2, K);
if (Code__Phrases__TypeData__block_follows(ph) == LOOP_BODY_BLOCK_FOLLOWS)
Code__Frames__Blocks__set_scope_to_block_about_to_open(lvar);
else
Code__Frames__Blocks__set_variable_scope(lvar);
tokens->args[i] =
Specifications__Storage__new_LOCAL_VARIABLE(
val->word_ref1, val->word_ref2, lvar);
if (Kinds__uses_pointer_values(K)) {
WRITE("%s = ", Code__LocalVariables__lvalue(lvar));
Code__Frames__compile_allocation(OUT, K);
WRITE("; ");
}
}
#line 81 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
}
#line 42 "inform7/Chapter 22/Compile Invocations Inline.w"
;
STREAM *TAIL = NULL;
if (Code__Phrases__TypeData__block_follows(ph) != NO_BLOCK_FOLLOWS)
Code__Frames__Blocks__beginning_block_phrase(OUT, ph);
char head_defn[MAX_INLINE_DEFN_LENGTH];
char tail_defn[MAX_INLINE_DEFN_LENGTH];
{
#line 140 "inform7/Chapter 22/Compile Invocations Inline.w"
char *p = Code__Routines__ToPhrases__get_inline_definition(ph);
Code__Invocations__Compiler__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 (Code__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;
Code__Invocations__Compiler__copy_and_trim(tail_defn, head_defn+i+8);
Code__Invocations__Compiler__trim_tail(head_defn);
break;
}
}
}
#line 51 "inform7/Chapter 22/Compile Invocations Inline.w"
;
{
#line 170 "inform7/Chapter 22/Compile Invocations Inline.w"
Code__Invocations__Compiler__csi_inline_inner(OUT, head_defn,
inv, where_from, tokens, append_close_brace, 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");
Code__Invocations__Compiler__csi_inline_inner(TAIL, tail_defn,
inv, where_from, tokens, append_close_brace, my_vars);
}
}
#line 52 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (Code__Phrases__TypeData__block_follows(ph))
{
#line 187 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *K = NULL;
if (Code__Invocations__get_number_tokens(inv) > 0)
K = Specifications__evaluates_to(tokens->args[0]);
Code__Frames__Blocks__open_code_block(OUT, ph, K, TAIL);
}
#line 54 "inform7/Chapter 22/Compile Invocations Inline.w"
else
{
#line 197 "inform7/Chapter 22/Compile Invocations Inline.w"
int i;
for (i=0; i<10; i++)
if (my_vars[i])
Code__LocalVariables__deallocate(my_vars[i]);
}
#line 55 "inform7/Chapter 22/Compile Invocations Inline.w"
;
return ph->inline_mor;
}
#line 205 "inform7/Chapter 22/Compile Invocations Inline.w"
void Code__Invocations__Compiler__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);
Code__Invocations__Compiler__trim_tail(to);
}
void Code__Invocations__Compiler__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 223 "inform7/Chapter 22/Compile Invocations Inline.w"
void Code__Invocations__Compiler__csi_inline_inner(OUTPUT_STREAM,
char *inline_definition, invocation *inv, source_location *where_from,
tokens_packet *tokens, int *append_close_brace, local_variable **my_vars) {
phrase *ph = inv->phrase_invoked;
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 243 "inform7/Chapter 22/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 286 "inform7/Chapter 22/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 322 "inform7/Chapter 22/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;
Text__feed_into_lexer(bracing+k+1, FALSE, NULL);
if (parse_nt_against_word_range(property_name_NTM, lexer_feed_w1, lexer_feed_w2, NULL, NULL))
extremal_property = most_recent_result_p;
break;
}
}
}
#line 291 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (command[0]) {
if (strcmp(command, "primitive-definition") == 0)
{
#line 1482 "inform7/Chapter 22/Compile Invocations Inline.w"
if (strcmp(bracing, "repeat-through") == 0)
Calculus__Deferrals__compile_repeat_through_domain_S(OUT,
tokens->args[1],
Specifications__Storage__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],
Specifications__Storage__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,
Properties__from_specification(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__inline_problem(_P_(C22InlineExtremal), 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 1540 "inform7/Chapter 22/Compile Invocations Inline.w"
specification *fn = tokens->args[0];
kind *fn_kind = Specifications__evaluates_to(fn);
kind *X = NULL, *Y = NULL;
if (Kinds__get_construct(fn_kind) != CON_phrase) {
Problems__quote_spec(4, fn);
Problems__inline_problem(_P_(C22InlineFunctionApplication),
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__uses_pointer_values(head)) && (Kinds__definite(head)))
tokens->kind_required[i-1] = head;
}
tokens->tokens_count--;
TEMPORARY_STREAM;
STREAM_WRITE(TEMP, "(");
Specifications__compile(TEMP, fn);
STREAM_WRITE(TEMP, "-->1)");
compile_function_call(OUT, tokens, STREAM_TEXT(TEMP), -1);
CLOSE_TEMPORARY_STREAM;
}
#line 1512 "inform7/Chapter 22/Compile Invocations Inline.w"
else if (strcmp(bracing, "description-application") == 0)
{
#line 1574 "inform7/Chapter 22/Compile Invocations Inline.w"
specification *fn = tokens->args[1];
tokens->args[1] = tokens->args[0];
tokens->args[0] = Specifications__Values__new_integer_literal(-1);
tokens->tokens_count = 2;
TEMPORARY_STREAM;
Specifications__compile(TEMP, fn);
compile_function_call(OUT, tokens, STREAM_TEXT(TEMP), -1);
CLOSE_TEMPORARY_STREAM;
}
#line 1513 "inform7/Chapter 22/Compile Invocations Inline.w"
else if (strcmp(bracing, "solve-equation") == 0)
{
#line 1586 "inform7/Chapter 22/Compile Invocations Inline.w"
if (Specifications__Values__is_CONSTANT_of_kind(tokens->args[1], K_equation))
Data__Equations__compile_solution(OUT,
tokens->args[0]->word_ref1, tokens->args[0]->word_ref2,
equation_spec_to_equation(tokens->args[1]));
else {
Problems__sentence_problem(_P_(C22SolvedNameless),
"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 1515 "inform7/Chapter 22/Compile Invocations Inline.w"
else if (strcmp(bracing, "break") == 0) Code__Frames__Blocks__compile_break(OUT);
else if (strcmp(bracing, "verbose-checking") == 0) {
char *what = "";
if (tokens->tokens_count > 0) {
specification *aspect = tokens->args[0];
int aw1 = aspect->word_ref1;
if (aw1 >= 0) {
Text__dequote_word(aw1); what = Text__word_text(aw1);
}
}
Log__Tracing__phrases(what);
}
else {
Problems__quote_text(4, bracing);
Problems__inline_problem(_P_(C22InlinePrimitive), ph, inline_definition,
"I don't know any primitive definition called '%4'.");
}
continue;
}
#line 294 "inform7/Chapter 22/Compile Invocations Inline.w"
;
{
#line 540 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__quote_text(4, bracing);
if (strcmp(command, "new") == 0)
{
#line 554 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *K = parse_bracing_operand_as_kind(bracing, inv->kind_variable_declarations);
if (Kinds__uses_pointer_values(K)) Code__Frames__compile_allocation(OUT, K);
else if (K == NULL)
{
#line 609 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__inline_problem(_P_(C22InlineNew), ph, inline_definition,
"I don't know any kind called '%4'.");
}
#line 556 "inform7/Chapter 22/Compile Invocations Inline.w"
else if (Kinds__compile_default_value(OUT, K, -1, -1, NULL) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__handmade_problem(_P_(C22NoNaturalDefault2));
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 541 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "new-list-of") == 0)
{
#line 578 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *K = parse_bracing_operand_as_kind(bracing, inv->kind_variable_declarations);
Calculus__Deferrals__compile_list_of_S(OUT, tokens->args[0], K);
continue;
}
#line 542 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "printing-routine") == 0)
{
#line 585 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *K = parse_bracing_operand_as_kind(bracing, inv->kind_variable_declarations);
if (K) WRITE("%s", Kinds__get_name_of_printing_rule(K));
else
{
#line 609 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__inline_problem(_P_(C22InlineNew), ph, inline_definition,
"I don't know any kind called '%4'.");
}
#line 587 "inform7/Chapter 22/Compile Invocations Inline.w"
;
continue;
}
#line 543 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "strong-kind") == 0)
{
#line 593 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *K = parse_bracing_operand_as_kind(bracing, inv->kind_variable_declarations);
if (K) Kinds__RuntimeIDs__compile_strong(OUT, K);
else
{
#line 609 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__inline_problem(_P_(C22InlineNew), ph, inline_definition,
"I don't know any kind called '%4'.");
}
#line 595 "inform7/Chapter 22/Compile Invocations Inline.w"
;
continue;
}
#line 544 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "weak-kind") == 0)
{
#line 601 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *K = parse_bracing_operand_as_kind(bracing, inv->kind_variable_declarations);
if (K) Kinds__RuntimeIDs__compile_weak(OUT, K);
else
{
#line 609 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__inline_problem(_P_(C22InlineNew), ph, inline_definition,
"I don't know any kind called '%4'.");
}
#line 603 "inform7/Chapter 22/Compile Invocations Inline.w"
;
continue;
}
#line 545 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
#line 295 "inform7/Chapter 22/Compile Invocations Inline.w"
;
{
#line 617 "inform7/Chapter 22/Compile Invocations Inline.w"
if (strcmp(command, "backspace") == 0)
{
#line 627 "inform7/Chapter 22/Compile Invocations Inline.w"
STREAM_BACKSPACE(OUT);
continue;
}
#line 617 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "erase") == 0)
{
#line 633 "inform7/Chapter 22/Compile Invocations Inline.w"
STREAM_ERASE_BACK_TO(start_position);
continue;
}
#line 618 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "open-brace") == 0)
{
#line 640 "inform7/Chapter 22/Compile Invocations Inline.w"
WRITE("{");
continue;
}
#line 619 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "close-brace") == 0)
{
#line 646 "inform7/Chapter 22/Compile Invocations Inline.w"
WRITE("}");
continue;
}
#line 620 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
#line 296 "inform7/Chapter 22/Compile Invocations Inline.w"
;
{
#line 653 "inform7/Chapter 22/Compile Invocations Inline.w"
if (strcmp(command, "label") == 0)
{
#line 684 "inform7/Chapter 22/Compile Invocations Inline.w"
Formats__Inform6__Labels__write(OUT, bracing);
continue;
}
#line 653 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "counter") == 0)
{
#line 690 "inform7/Chapter 22/Compile Invocations Inline.w"
WRITE("%d", Formats__Inform6__Labels__Counters__read(bracing, NOT_APPLICABLE));
continue;
}
#line 654 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "counter-up") == 0)
{
#line 696 "inform7/Chapter 22/Compile Invocations Inline.w"
Formats__Inform6__Labels__Counters__read(bracing, TRUE);
continue;
}
#line 655 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "counter-down") == 0)
{
#line 703 "inform7/Chapter 22/Compile Invocations Inline.w"
Formats__Inform6__Labels__Counters__read(bracing, FALSE);
continue;
}
#line 656 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "counter-makes-array") == 0)
{
#line 733 "inform7/Chapter 22/Compile Invocations Inline.w"
int words_per_count = 1;
if (operand2[0]) words_per_count = atoi(operand2);
Formats__Inform6__Labels__Counters__allocate(bracing, words_per_count);
continue;
}
#line 657 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
#line 297 "inform7/Chapter 22/Compile Invocations Inline.w"
;
{
#line 979 "inform7/Chapter 22/Compile Invocations Inline.w"
if (strcmp(command, "my") == 0)
{
#line 994 "inform7/Chapter 22/Compile Invocations Inline.w"
local_variable *lvar = NULL;
int n = bracing[0] - '0';
if ((bracing[1] == 0) && (n >= 0) && (n < 10))
{
#line 1024 "inform7/Chapter 22/Compile Invocations Inline.w"
lvar = my_vars[n];
if (lvar == NULL) {
my_vars[n] = Code__LocalVariables__new(-1, -1, K_number);
lvar = my_vars[n];
{
#line 1073 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *K = NULL;
if (operand2[0])
K = parse_bracing_operand_as_kind(operand2, inv->kind_variable_declarations);
if (K == NULL) K = K_object;
Code__LocalVariables__set_kind(lvar, K);
}
#line 1028 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (Code__Phrases__TypeData__block_follows(ph))
Code__Frames__Blocks__set_scope_to_block_about_to_open(lvar);
}
}
#line 996 "inform7/Chapter 22/Compile Invocations Inline.w"
else
{
#line 1061 "inform7/Chapter 22/Compile Invocations Inline.w"
lvar = Code__LocalVariables__add_internal_local(bracing);
{
#line 1073 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *K = NULL;
if (operand2[0])
K = parse_bracing_operand_as_kind(operand2, inv->kind_variable_declarations);
if (K == NULL) K = K_object;
Code__LocalVariables__set_kind(lvar, K);
}
#line 1062 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
#line 997 "inform7/Chapter 22/Compile Invocations Inline.w"
;
WRITE("%s", Code__LocalVariables__lvalue(lvar));
continue;
}
#line 979 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "unprotect") == 0)
{
#line 1096 "inform7/Chapter 22/Compile Invocations Inline.w"
specification *v =
parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
local_variable *lvar = Specifications__Storage__get_local_variable_if_any(v);
if (lvar) Code__LocalVariables__unprotect(lvar);
else
{
#line 1602 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__quote_text(4, bracing);
Problems__inline_problem(_P_(C22InlineNoSuch), ph, inline_definition,
"I don't know any local variable called '%4'.");
}
#line 1100 "inform7/Chapter 22/Compile Invocations Inline.w"
;
continue;
}
#line 980 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "copy") == 0)
{
#line 1180 "inform7/Chapter 22/Compile Invocations Inline.w"
int copy_form = 0;
specification *from = NULL, *to = NULL;
{
#line 1211 "inform7/Chapter 22/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 = Specifications__Values__new_integer_literal(1);
else if (from_p[0])
from = parse_bracing_operand_as_identifier(from_p, ph, tokens, my_vars);
to = 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__inline_problem(_P_(C22InlineCopy), 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 1182 "inform7/Chapter 22/Compile Invocations Inline.w"
;
{
#line 1237 "inform7/Chapter 22/Compile Invocations Inline.w"
nonlocal_variable *nlv = Specifications__Storage__get_nonlocal_variable_if_any(to);
if ((nlv) && (Data__NonlocalVariables__must_be_constant(nlv))) continue;
if (nlv) Data__NonlocalVariables__warn_about_change(nlv);
local_variable *lvar = Specifications__Storage__get_local_variable_if_any(to);
if ((lvar) && (Code__LocalVariables__protected(lvar))) continue;
}
#line 1183 "inform7/Chapter 22/Compile Invocations Inline.w"
;
pcalc_term pt1 = Calculus__Terms__new_constant(to);
pcalc_term pt2 = Calculus__Terms__new_constant(from);
kind *K1 = Specifications__evaluates_to(to);
kind *K2 = Specifications__evaluates_to(from);
int storage_class = Specifications__Storage__get_storage_form(to);
if (copy_form != 0)
{
#line 1247 "inform7/Chapter 22/Compile Invocations Inline.w"
if (Kinds__is_quasinumerical(K1) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K1);
Problems__handmade_problem(_P_(C22CantIncrementKind));
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 1190 "inform7/Chapter 22/Compile Invocations Inline.w"
;
char *prototype = Kinds__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);
Code__Schemas__expand(Code__Schemas__new("%s;", prototype), OUT, &pt1, &pt2);
END_COMPILATION_MODE;
continue;
}
#line 981 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "initialise") == 0)
{
#line 1120 "inform7/Chapter 22/Compile Invocations Inline.w"
specification *V = parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
local_variable *lvar = Specifications__Storage__get_local_variable_if_any(V);
kind *K = NULL;
if (operand2[0])
K = parse_bracing_operand_as_kind(operand2, inv->kind_variable_declarations);
else
K = Specifications__evaluates_to(V);
if (Kinds__uses_pointer_values(K)) {
if (Code__Frames__Blocks__inside_a_loop_body()) {
WRITE("BlkValueCopy(%s, ", Code__LocalVariables__lvalue(lvar));
Kinds__compile_default_value(OUT, K, V->word_ref1, V->word_ref2, "value");
WRITE("); ");
}
} else {
WRITE("%s = ", Code__LocalVariables__lvalue(lvar));
if (Kinds__compile_default_value(OUT, K, V->word_ref1, V->word_ref2, "value") == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__handmade_problem(_P_(C22NoNaturalDefault));
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 982 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "matches-description") == 0)
{
#line 1281 "inform7/Chapter 22/Compile Invocations Inline.w"
specification *to_match =
parse_bracing_operand_as_identifier(operand2, ph, tokens, my_vars);
specification *to_test =
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__inline_problem(_P_(C22InlineMatchesDescription), 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 983 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "now-matches-description") == 0)
{
#line 1300 "inform7/Chapter 22/Compile Invocations Inline.w"
specification *to_test =
parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
specification *to_match =
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__inline_problem(_P_(C22InlineNowMatchesDescription),
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 984 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "arithmetic-operation") == 0)
{
#line 1319 "inform7/Chapter 22/Compile Invocations Inline.w"
int op = Code__Phrases__TypeData__arithmetic_operation(ph);
int binary = TRUE;
if ((op == ROOT_OPERATION) || (op == CUBEROOT_OPERATION)) binary = FALSE;
specification *X = NULL, *Y = NULL;
kind *KX = NULL, *KY = NULL;
{
#line 1331 "inform7/Chapter 22/Compile Invocations Inline.w"
X = parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
KX = Specifications__evaluates_to(X);
if (binary) {
Y = parse_bracing_operand_as_identifier(operand2, ph, tokens, my_vars);
KY = Specifications__evaluates_to(Y);
}
}
#line 1324 "inform7/Chapter 22/Compile Invocations Inline.w"
;
Kinds__perform_arithmetic(OUT, op, NULL, X, NULL, KX, Y, NULL, KY);
continue;
}
#line 985 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "say") == 0)
{
#line 1345 "inform7/Chapter 22/Compile Invocations Inline.w"
specification *to_say =
parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
if (to_say == NULL) {
{
#line 1602 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__quote_text(4, bracing);
Problems__inline_problem(_P_(C22InlineNoSuch), ph, inline_definition,
"I don't know any local variable called '%4'.");
}
#line 1348 "inform7/Chapter 22/Compile Invocations Inline.w"
;
continue;
}
int s1 = to_say->word_ref1, s2 = to_say->word_ref2;
if ((Specifications__Values__is_actual_CONSTANT_of_kind(to_say, K_text)) &&
(Text__Vocabulary__test_flags(s1, TEXTWITHSUBS_MC) == FALSE) && (s1 == s2)) {
WRITE("print \"");
Formats__Inform6__compile_string(OUT, Text__word_text(s1),
ISN_DEQUOTE + ISN_EXPAND_APOSTROPHES);
WRITE("\";");
} else {
kind *K = Specifications__evaluates_to(to_say);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
WRITE("print (");
if (K) WRITE("%s", Kinds__get_name_of_printing_rule(K));
WRITE(") "); Specifications__compile_to_kind(OUT, to_say, K);
WRITE(";");
END_COMPILATION_MODE;
}
continue;
}
#line 986 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "show-me") == 0)
{
#line 1374 "inform7/Chapter 22/Compile Invocations Inline.w"
specification *to_show =
parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
if (to_show == NULL) {
{
#line 1602 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__quote_text(4, bracing);
Problems__inline_problem(_P_(C22InlineNoSuch), ph, inline_definition,
"I don't know any local variable called '%4'.");
}
#line 1377 "inform7/Chapter 22/Compile Invocations Inline.w"
;
continue;
}
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
WRITE("#ifdef DEBUG;");
WRITE("print \"");
Plugins__Parsing__TestScripts__Internal__showme(OUT, to_show);
WRITE("^\";");
WRITE("#endif;\n");
END_COMPILATION_MODE;
continue;
}
#line 987 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
#line 298 "inform7/Chapter 22/Compile Invocations Inline.w"
;
{
#line 1395 "inform7/Chapter 22/Compile Invocations Inline.w"
if (strcmp(command, "segment-count") == 0)
{
#line 1404 "inform7/Chapter 22/Compile Invocations Inline.w"
WRITE("%d", inv->ssp_segment_count);
continue;
}
#line 1395 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "final-segment-marker") == 0)
{
#line 1410 "inform7/Chapter 22/Compile Invocations Inline.w"
if (inv->ssp_closing_segment_wn == -1) WRITE("NULL");
else {
char plenty[1024];
Text__print_text_to_string(inv->ssp_closing_segment_wn,
inv->ssp_closing_segment_wn, plenty);
WRITE("%s", plenty);
}
continue;
}
#line 1396 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "list-together") == 0)
{
#line 1423 "inform7/Chapter 22/Compile Invocations Inline.w"
if (strcmp(bracing, "unarticled") == 0)
Code__ListTogether__new(OUT, FALSE);
else if (strcmp(bracing, "articled") == 0)
Code__ListTogether__new(OUT, TRUE);
else {
Problems__inline_problem(_P_(C22InlineListTogether), ph, inline_definition,
"The only legal forms here are {-list-together:articled} and "
"{-list-together:unarticled}.");
}
continue;
}
#line 1397 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "rescale") == 0)
{
#line 1439 "inform7/Chapter 22/Compile Invocations Inline.w"
int op = Code__Phrases__TypeData__arithmetic_operation(ph);
switch (op) {
case TIMES_OPERATION: {
kind *kindx = Specifications__evaluates_to(tokens->args[0]);
kind *kindy = Specifications__evaluates_to(tokens->args[1]);
Kinds__Dimensions__kind_rescale_multiplication(OUT, kindx, kindy);
break;
}
case DIVIDE_OPERATION: {
kind *kindx = Specifications__evaluates_to(tokens->args[0]);
kind *kindy = Specifications__evaluates_to(tokens->args[1]);
Kinds__Dimensions__kind_rescale_division(OUT, kindx, kindy);
break;
}
case ROOT_OPERATION: {
kind *K = Specifications__evaluates_to(tokens->args[0]);
Kinds__Dimensions__kind_rescale_root(OUT, K, 2);
break;
}
case CUBEROOT_OPERATION: {
kind *K = Specifications__evaluates_to(tokens->args[0]);
Kinds__Dimensions__kind_rescale_root(OUT, K, 3);
break;
}
default:
Problems__inline_problem(_P_(C22InlineRescale), ph, inline_definition,
"Arithmetic rescaling with {-rescale} is allowed only in phrases "
"which multiply, divide or extract roots.");
break;
}
continue;
}
#line 1398 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
#line 299 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
Text__feed_into_lexer(bracing, FALSE, NULL);
int brace_w1 = lexer_feed_w1, brace_w2 = lexer_feed_w2;
{
#line 413 "inform7/Chapter 22/Compile Invocations Inline.w"
phod_being_parsed = &(ph->options_data);
ph_being_parsed = ph;
parse_nt_against_word_range(inline_substitution_NTM, brace_w1, brace_w2, NULL, NULL);
int current_opts = Code__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 = Code__LocalVariables__get_parameter_number(lvar);
if (tok >= 0)
{
#line 437 "inform7/Chapter 22/Compile Invocations Inline.w"
specification *required = ph->type_data.token_sequence[tok].to_match;
specification *supplied = tokens->args[tok];
int by_value_not_reference = TRUE;
int require_to_be_lvalue = FALSE;
{
#line 467 "inform7/Chapter 22/Compile Invocations Inline.w"
if ((Specifications__family_is(required, COMMAND_FMY)) &&
(Specifications__species_is(required, UNKNOWN))) {
*append_close_brace = TRUE;
WRITE("{ ");
}
}
#line 443 "inform7/Chapter 22/Compile Invocations Inline.w"
;
BEGIN_COMPILATION_MODE;
{
#line 744 "inform7/Chapter 22/Compile Invocations Inline.w"
int valid_annotation = FALSE;
if (strcmp(command, "by-reference") == 0)
{
#line 771 "inform7/Chapter 22/Compile Invocations Inline.w"
by_value_not_reference = FALSE;
valid_annotation = TRUE;
}
#line 746 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "lvalue-by-reference") == 0)
{
#line 783 "inform7/Chapter 22/Compile Invocations Inline.w"
by_value_not_reference = FALSE;
valid_annotation = TRUE;
require_to_be_lvalue = TRUE;
}
#line 747 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "by-value") == 0)
{
#line 790 "inform7/Chapter 22/Compile Invocations Inline.w"
by_value_not_reference = TRUE;
valid_annotation = TRUE;
}
#line 748 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "box-quotation-text") == 0)
{
#line 799 "inform7/Chapter 22/Compile Invocations Inline.w"
if (Specifications__Values__is_CONSTANT_of_kind(supplied, K_text) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_spec(2, supplied);
Problems__handmade_problem(_P_(C22Misboxed));
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 750 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "return-value") == 0)
{
#line 839 "inform7/Chapter 22/Compile Invocations Inline.w"
int returning_from_rule = FALSE;
{
#line 852 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *kind_needed;
if (returning_from_rule) kind_needed = Code__Rulebooks__kind_from_context();
else kind_needed = Code__Frames__get_kind_returned();
kind *kind_supplied = Specifications__evaluates_to(supplied);
int mor = Code__Phrases__TypeData__get_mor(&(phrase_being_compiled->type_data));
int allow_me = ALWAYS_MATCH;
if ((kind_needed) && (Kinds__eq(kind_needed, K_nil) == FALSE))
allow_me = Kinds__compatible(kind_supplied, kind_needed);
else if ((mor == DECIDES_CONDITION_MOR) && (Kinds__eq(kind_supplied, K_truth_state)))
allow_me = ALWAYS_MATCH;
else
{
#line 879 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind_of(2, supplied);
if (returning_from_rule) {
Problems__handmade_problem(_P_(C22RuleNotAllowedOutcome));
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__handmade_problem(_P_(C22RedundantReturnKOV));
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 864 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (allow_me == ALWAYS_MATCH)
Specifications__compile_to_kind(OUT, supplied, kind_needed);
else if ((allow_me == SOMETIMES_MATCH) && (Kinds__le(kind_needed, K_object))) {
WRITE("CheckKindReturned(");
Specifications__compile_to_kind(OUT, supplied, kind_needed);
WRITE(", %s)", Kinds__I6_classname(kind_needed));
} else
{
#line 899 "inform7/Chapter 22/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__handmade_problem(_P_(C22RuleOutcomeWrongKind));
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__handmade_problem(_P_(C22ReturnWrongKind));
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 872 "inform7/Chapter 22/Compile Invocations Inline.w"
;
continue; /* that is, don't use the regular token compiler: we've done it ourselves */
}
#line 840 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
#line 752 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "return-value-from-rule") == 0)
{
#line 846 "inform7/Chapter 22/Compile Invocations Inline.w"
int returning_from_rule = TRUE;
{
#line 852 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *kind_needed;
if (returning_from_rule) kind_needed = Code__Rulebooks__kind_from_context();
else kind_needed = Code__Frames__get_kind_returned();
kind *kind_supplied = Specifications__evaluates_to(supplied);
int mor = Code__Phrases__TypeData__get_mor(&(phrase_being_compiled->type_data));
int allow_me = ALWAYS_MATCH;
if ((kind_needed) && (Kinds__eq(kind_needed, K_nil) == FALSE))
allow_me = Kinds__compatible(kind_supplied, kind_needed);
else if ((mor == DECIDES_CONDITION_MOR) && (Kinds__eq(kind_supplied, K_truth_state)))
allow_me = ALWAYS_MATCH;
else
{
#line 879 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind_of(2, supplied);
if (returning_from_rule) {
Problems__handmade_problem(_P_(C22RuleNotAllowedOutcome));
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__handmade_problem(_P_(C22RedundantReturnKOV));
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 864 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (allow_me == ALWAYS_MATCH)
Specifications__compile_to_kind(OUT, supplied, kind_needed);
else if ((allow_me == SOMETIMES_MATCH) && (Kinds__le(kind_needed, K_object))) {
WRITE("CheckKindReturned(");
Specifications__compile_to_kind(OUT, supplied, kind_needed);
WRITE(", %s)", Kinds__I6_classname(kind_needed));
} else
{
#line 899 "inform7/Chapter 22/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__handmade_problem(_P_(C22RuleOutcomeWrongKind));
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__handmade_problem(_P_(C22ReturnWrongKind));
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 872 "inform7/Chapter 22/Compile Invocations Inline.w"
;
continue; /* that is, don't use the regular token compiler: we've done it ourselves */
}
#line 847 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
#line 753 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "property-holds-block-value") == 0)
{
#line 921 "inform7/Chapter 22/Compile Invocations Inline.w"
property *prn = Specifications__Values__get_property_name_if_any(supplied);
if ((prn == NULL) || (Properties__is_either_or(prn))) {
WRITE("false");
} else {
kind *K = Properties__Valued__kind(prn);
if (Kinds__uses_pointer_values(K)) WRITE("true"); else WRITE("false");
}
continue;
}
#line 755 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if (strcmp(command, "mark-event-used") == 0)
{
#line 943 "inform7/Chapter 22/Compile Invocations Inline.w"
if (Specifications__Values__is_CONSTANT_construction(supplied, CON_rule)) {
rule *R = Code__Rules__from_specification(supplied);
phrase *ph = Code__Rules__get_I7_definition(R);
if (ph) Code__Phrases__Timed__note_usage(ph, current_sentence);
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, supplied->word_ref1, supplied->word_ref2);
Problems__handmade_problem(_P_(C22NonconstantEvent));
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 756 "inform7/Chapter 22/Compile Invocations Inline.w"
;
if ((command[0]) && (valid_annotation == FALSE))
{
#line 963 "inform7/Chapter 22/Compile Invocations Inline.w"
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, command);
Problems__handmade_problem(_P_(C22BadInlineTag));
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 759 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
#line 446 "inform7/Chapter 22/Compile Invocations Inline.w"
;
kind *kind_vars_inline[27];
{
#line 476 "inform7/Chapter 22/Compile Invocations Inline.w"
int i;
for (i=0; i<27; i++) kind_vars_inline[i] = NULL;
kind_variable_declaration *kvd = inv->kind_variable_declarations;
for (; kvd; kvd=kvd->next) kind_vars_inline[kvd->kv_number] = kvd->kv_value;
}
#line 448 "inform7/Chapter 22/Compile Invocations Inline.w"
;
kind **saved = Code__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 484 "inform7/Chapter 22/Compile Invocations Inline.w"
if (require_to_be_lvalue) {
if (Specifications__family_is(supplied, STORAGE_FMY) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_spec(2, supplied);
Problems__handmade_problem(_P_(C22NotAnLvalue));
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 454 "inform7/Chapter 22/Compile Invocations Inline.w"
;
{
#line 518 "inform7/Chapter 22/Compile Invocations Inline.w"
if (Kinds__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 $S into '$W' with %d, $u%s%s\n",
supplied, brace_w1, brace_w2, tok, kind_required,
changed?" (after kind substitution)":"",
by_value_not_reference?" (by value)":" (by reference)");
Specifications__compile_to_kind(OUT, supplied, kind_required);
}
#line 455 "inform7/Chapter 22/Compile Invocations Inline.w"
;
Code__Frames__temporarily_set_kvs(saved);
END_COMPILATION_MODE;
}
#line 427 "inform7/Chapter 22/Compile Invocations Inline.w"
;
break;
}
}
}
#line 304 "inform7/Chapter 22/Compile Invocations Inline.w"
;
}
#line 253 "inform7/Chapter 22/Compile Invocations Inline.w"
else { WRITE("{"); pos = save_pos; }
}
#line 232 "inform7/Chapter 22/Compile Invocations Inline.w"
else if ((inline_definition[pos] == '(') && (inline_definition[pos+1] == '+'))
{
#line 259 "inform7/Chapter 22/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 275 "inform7/Chapter 22/Compile Invocations Inline.w"
if (source_text_fragment[0]) {
TEMPORARY_STREAM;
Config__Template__compile_I7_from_I6(TEMP, source_text_fragment);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
}
#line 269 "inform7/Chapter 22/Compile Invocations Inline.w"
else { WRITE("("); pos = save_pos; }
}
#line 234 "inform7/Chapter 22/Compile Invocations Inline.w"
else
WRITE("%c", inline_definition[pos]);
}
#line 373 "inform7/Chapter 22/Compile Invocations Inline.w"
int inline_substitution_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 395 "inform7/Chapter 22/Compile Invocations Inline.w"
*X = PROBLEM_INSUB;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C22BadInlineExpansion));
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 377 "inform7/Chapter 22/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 378 "inform7/Chapter 22/Compile Invocations Inline.w"
#line 382 "inform7/Chapter 22/Compile Invocations Inline.w"
int name_local_to_inline_stack_frame_NTMR(int w1, int w2, int *X, void **XP) {
#line 383 "inform7/Chapter 22/Compile Invocations Inline.w"
local_variable *lvar =
Code__LocalVariables__parse(&(ph_being_parsed->stack_frame), w1, w2);
if (lvar) {
*XP = lvar; return TRUE;
}
return FALSE;
}
#line 1618 "inform7/Chapter 22/Compile Invocations Inline.w"
specification *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 {
Text__feed_into_lexer(operand, FALSE, NULL);
lvar = Code__LocalVariables__parse(&(ph->stack_frame), lexer_feed_w1, lexer_feed_w2);
if (lvar) {
int tok = Code__LocalVariables__get_parameter_number(lvar);
if (tok >= 0) return tokens->args[tok];
}
lvar = Code__LocalVariables__by_name(operand);
}
if (lvar) return Specifications__Storage__new_LOCAL_VARIABLE(-1, -1, lvar);
return NULL;
}
#line 1654 "inform7/Chapter 22/Compile Invocations Inline.w"
kind *parse_bracing_operand_as_kind(char *operand, kind_variable_declaration *kvd) {
if (strcmp(operand, "return-kind") == 0)
return Code__Frames__get_kind_returned();
if (strcmp(operand, "rule-return-kind") == 0)
return Code__Rulebooks__kind_from_context();
kind *kind_vars_inline[27];
int i;
for (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 = Code__Frames__temporarily_set_kvs(kind_vars_inline);
int kw1 = lexer_wordcount, kw2 = -1;
Text__feed_into_lexer(operand, FALSE, NULL);
kw2 = lexer_wordcount - 1;
specification *spec = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, kw1, kw2, NULL, NULL)) spec = most_recent_result_p;
Code__Frames__temporarily_set_kvs(saved);
kind *K = Specifications__get_kind_referred_to(spec);
return K;
}
#line 30 "inform7/Chapter 22/Compile Phrases.w"
void Code__Routines__compile(OUTPUT_STREAM, phrase *ph,
stacked_variable_owner_list *legible, to_phrase_request *req,
applicability_condition *acl) {
if ((ph->declaration_node == NULL) ||
(Parser__Nodes__type(ph->declaration_node) != ROUTINE_NT) ||
(ph->declaration_node->word_ref1 < 0))
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 73 "inform7/Chapter 22/Compile Phrases.w"
ph_stack_frame *phsf = &(ph->stack_frame);
ph_type_data *phtd = &(ph->type_data);
Code__Frames__make_current(phsf);
kind *version_kind = NULL;
if (req) version_kind = Code__Routines__ToPhrases__Requests__kind(req);
else version_kind = Code__Phrases__TypeData__kind(phtd);
Code__Phrases__TypeData__into_stack_frame(phsf, phtd, version_kind, FALSE);
if (req) Code__Frames__set_kind_variables(phsf,
Code__Routines__ToPhrases__Requests__kind_variables(req));
else Code__Frames__set_kind_variables(phsf, NULL);
Code__Frames__set_stvol(phsf, legible);
Code__LocalVariables__deallocate_all(phsf); /* in case any are left from an earlier compile */
Specifications__warn_expression_cache(); /* that local variables may have changed */
}
#line 41 "inform7/Chapter 22/Compile Phrases.w"
;
{
#line 60 "inform7/Chapter 22/Compile Phrases.w"
heading *definition_area =
Parser__Sentences__Headings__heading_of(
Text__word_location(ph->declaration_node->word_ref1));
extension_file *definition_extension =
Parser__Sentences__Headings__get_extension_containing(definition_area);
if (definition_extension)
Extensions__Files__write_I6_comment_describing(definition_extension, OUT);
Code__Routines__ToPhrases__Requests__write_I6_comment_describing(req, OUT);
Code__Phrases__Usage__write_I6_comment_describing(&(ph->usage_data), OUT);
}
#line 43 "inform7/Chapter 22/Compile Phrases.w"
;
char i6_routine_identifier[32];
Code__Routines__compile_identifier(i6_routine_identifier, ph, req);
OUT = Code__Routines__begin_framed(OUT, i6_routine_identifier, &(ph->stack_frame));
{
#line 94 "inform7/Chapter 22/Compile Phrases.w"
current_sentence = ph->declaration_node;
Code__Phrases__Context__compile_test_head(OUT, ph, acl);
int statement_count = 1;
parse_node *p;
for (p = ph->declaration_node->down; p; p = p->next) {
current_sentence = p;
Code__Frames__Blocks__make_indentation_follow_code(OUT);
{
#line 114 "inform7/Chapter 22/Compile Phrases.w"
WRITE("! [%d: ", statement_count++);
Formats__Inform6__compile_as_comment(OUT, p->word_ref1, p->word_ref2);
WRITE("]\n");
}
#line 102 "inform7/Chapter 22/Compile Phrases.w"
;
Code__Routines__ToPhrases__compile_line(OUT, p->word_ref1, p->word_ref2);
WRITE("\n");
}
current_sentence = ph->declaration_node;
Code__Phrases__Context__compile_test_tail(OUT, ph, acl);
{
#line 124 "inform7/Chapter 22/Compile Phrases.w"
kind *K = Code__Frames__get_kind_returned();
if (K) {
WRITE("return ");
if (Kinds__compile_default_value(OUT, K, -1, -1,
"value decided by this phrase") != TRUE)
Problems__sentence_problem(_P_(C22DefaultDecideFails),
"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 109 "inform7/Chapter 22/Compile Phrases.w"
;
}
#line 49 "inform7/Chapter 22/Compile Phrases.w"
;
OUT = Code__Routines__end(OUT);
phrase_being_compiled = NULL;
current_sentence = NULL;
}
#line 143 "inform7/Chapter 22/Compile Phrases.w"
void Code__Routines__compile_identifier(char *identifier, phrase *ph, to_phrase_request *req) {
if (req)
sprintf(identifier, "%s_r%d ",
Code__Phrases__identifier(ph), req->allocation_id);
else
strcpy(identifier, Code__Phrases__identifier(ph));
}
#line 155 "inform7/Chapter 22/Compile Phrases.w"
specification *void_phrase_please = NULL; /* instructions for the typechecker */
void Code__Routines__ToPhrases__compile_line(OUTPUT_STREAM, int w1, int w2) {
int initial_problem_count = problem_count;
LOGIF(EXPRESSIONS, "\n-- -- Evaluating <$W> -- --\n", w1, w2);
LOGIF(EXPRESSIONS, "(a) Parsing:\n");
specification *parsed;
if (parse_nt_against_word_range(spec_command_NTM, w1, w2, NULL, NULL)) parsed = most_recent_result_p;
else parsed = Specifications__Unknown__new(w1, w2);
Parser__SP__MeaningLists__finish_this_session();
if (initial_problem_count == problem_count) {
LOGIF(EXPRESSIONS, "(b) Type checking as $S:\n$X", void_phrase_please, parsed);
if (void_phrase_please == NULL) void_phrase_please = Specifications__Commands__new();
Specifications__Matching__check(parsed, void_phrase_please);
}
if (initial_problem_count == problem_count) {
LOGIF(EXPRESSIONS, "(c) Compilation:\n");
if (Specifications__has_invocation_list(parsed))
LOGIF(MATCHING, "Invocation list to be compiled:\n$E\n",
Specifications__invocation_list(parsed));
Specifications__compile(OUT, parsed);
}
if (initial_problem_count == problem_count) {
LOGIF(EXPRESSIONS, "-- -- Completed -- --\n");
} else {
LOGIF(EXPRESSIONS, "-- -- Failed -- --\n");
}
}
#line 189 "inform7/Chapter 22/Compile Phrases.w"
parse_node *Code__Routines__code_line(void) {
if (phrase_being_compiled) return current_sentence;
return NULL;
}
#line 54 "inform7/Chapter 22/To Phrases.w"
int ph_To_compare(phrase *ph1, phrase *ph2) {
int r = Code__Phrases__TypeData__comparison(&(ph1->type_data), &(ph2->type_data));
if ((Log__Aspects__on(PHRASE_COMPARISONS_DA)) || (r == CONFLICTED_PH)) {
LOG("Phrase comparison (");
Code__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(" (");
Code__Phrases__write_HTML_representation(dl, ph2, PASTE_PHRASE_FORMAT);
LOG(")\n");
}
if (r == CONFLICTED_PH) {
Problems__quote_source(1, Code__Phrases__declaration_node(ph1));
Problems__quote_source(2, Code__Phrases__declaration_node(ph2));
Problems__handmade_problem(_P_(C22ConflictedReturnKinds));
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 22/To Phrases.w"
void Code__Routines__ToPhrases__new(phrase *ph) {
phrase *previous_phrase = NULL;
phrase *current_phrase = first_in_logical_order;
sprintf(Code__Phrases__identifier(ph), "PHR_%d", ph->allocation_id);
if (first_in_logical_order == NULL) { first_in_logical_order = ph; return; }
while ((current_phrase != NULL) &&
(ph_To_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 22/To Phrases.w"
void Code__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;
Code__Phrases__TypeData__register_excerpt(ph);
ph->sequence_count = c++;
}
}
int Code__Routines__ToPhrases__sequence_count(phrase *ph) {
if (ph == NULL) return 0;
if (ph->sequence_count == -1) {
Code__Phrases__log(ph);
internal_error("Sequence count not ready");
}
return ph->sequence_count;
}
#line 160 "inform7/Chapter 22/To Phrases.w"
to_phrase_request *Code__Routines__ToPhrases__Requests__make(phrase *ph, kind *K,
kind_variable_declaration *kvd, int w1, int w2) {
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__eq(K, req->requested_exact_kind)))
return req;
if (Kinds__semidefinite(K) == FALSE)
{
#line 191 "inform7/Chapter 22/To Phrases.w"
Problems__quote_source(1, Code__Phrases__declaration_node(ph));
Problems__handmade_problem(_P_(C22UndeterminedKind));
if (w1 < 0) {
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_words_as_source(2, w1, w2);
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 22/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 22/To Phrases.w"
void Code__Routines__ToPhrases__Requests__make_identifier(char *identifier,
phrase *ph, kind *req_kind) {
if (Code__Phrases__TypeData__invoked_inline(ph)) {
char *p = Code__Routines__ToPhrases__get_inline_definition(ph);
strcpy(identifier, "0");
int i;
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;
break;
}
} else {
to_phrase_request *req = Code__Routines__ToPhrases__Requests__make(
ph, req_kind, NULL, -1, -1);
Code__Routines__compile_identifier(identifier, ph, req);
}
}
#line 237 "inform7/Chapter 22/To Phrases.w"
to_phrase_request *latest_request_granted = NULL;
int Code__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;
Code__Phrases__compile(OUT, latest_request_granted->requested_phrase,
i, max_i, NULL, latest_request_granted, NULL);
N++;
}
return N;
}
#line 258 "inform7/Chapter 22/To Phrases.w"
void Code__Routines__ToPhrases__Requests__write_I6_comment_describing(
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 272 "inform7/Chapter 22/To Phrases.w"
kind *Code__Routines__ToPhrases__Requests__kind(to_phrase_request *req) {
if (req == NULL) internal_error("null request");
return req->requested_exact_kind;
}
kind **Code__Routines__ToPhrases__Requests__kind_variables(to_phrase_request *req) {
if (req == NULL) internal_error("null request");
return req->kind_variables_interpretation;
}
#line 287 "inform7/Chapter 22/To Phrases.w"
int Code__Routines__ToPhrases__allows_options(phrase *ph) {
return Code__Phrases__Options__allows_options(&(ph->options_data));
}
int Code__Routines__ToPhrases__parse_phrase_option_used(phrase *ph, int w1, int w2) {
return Code__Phrases__Options__parse(&(ph->options_data), w1, w2);
}
#line 38 "inform7/Chapter 22/Say Phrases.w"
int Code__Invocations__Compiler__verify(invocation_list *invl) {
int problem_issued = FALSE;
int say_invocations_found = 0;
{
#line 56 "inform7/Chapter 22/Say 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];
invocation *SSP_invocations[MAX_COMPLEX_SAY_DEPTH];
int say_if_nesting = 0;
INVOCATION_VARIABLE(inv);
LOOP_THROUGH_INVOCATION_LIST(inv, invl) {
if ((inv->phrase_invoked) &&
(Code__Phrases__TypeData__is_a_say_phrase(inv->phrase_invoked))) {
int say_cs, ssp_tok, ssp_ctok, ssp_pos;
Code__Phrases__TypeData__get_say_data(&(inv->phrase_invoked->type_data.as_say),
&say_cs, &ssp_tok, &ssp_ctok, &ssp_pos);
if (ssp_pos == SSP_START)
{
#line 96 "inform7/Chapter 22/Say Phrases.w"
SSP_invocations[SSP_sp] = inv;
SSP_stack_otherwised[SSP_sp] = FALSE;
SSP_stack[SSP_sp++] = ssp_tok;
}
#line 72 "inform7/Chapter 22/Say Phrases.w"
;
if (ssp_pos == SSP_MIDDLE)
{
#line 103 "inform7/Chapter 22/Say Phrases.w"
if ((SSP_sp > 0) && (SSP_stack[SSP_sp-1] != -1) &&
(compare_words(SSP_stack[SSP_sp-1], ssp_tok))) {
SSP_invocations[SSP_sp-1]->ssp_segment_count++;
inv->ssp_segment_count = SSP_invocations[SSP_sp-1]->ssp_segment_count;
} else
{
#line 157 "inform7/Chapter 22/Say Phrases.w"
if (problem_issued == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, inv->invocation_w1, inv->invocation_w2);
Problems__handmade_problem(_P_(C22ComplicatedSayStructure));
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.");
Code__Phrases__add_say_construction_to_error(ssp_tok);
Problems__issue_problem_end();
problem_issued = TRUE;
}
}
#line 107 "inform7/Chapter 22/Say Phrases.w"
;
}
#line 73 "inform7/Chapter 22/Say Phrases.w"
;
if (ssp_pos == SSP_END)
{
#line 112 "inform7/Chapter 22/Say Phrases.w"
if ((SSP_sp > 0) && (SSP_stack[SSP_sp-1] != -1) &&
(compare_words(SSP_stack[SSP_sp-1], ssp_tok))) {
SSP_invocations[SSP_sp-1]->ssp_segment_count++;
SSP_invocations[SSP_sp-1]->ssp_closing_segment_wn = ssp_ctok;
inv->ssp_segment_count = SSP_invocations[SSP_sp-1]->ssp_segment_count;
SSP_sp--;
} else
{
#line 172 "inform7/Chapter 22/Say Phrases.w"
if (problem_issued == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, inv->invocation_w1, inv->invocation_w2);
Problems__handmade_problem(_P_(C22ComplicatedSayStructure2));
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.");
Code__Phrases__add_say_construction_to_error(ssp_tok);
Problems__issue_problem_end();
problem_issued = TRUE;
}
}
#line 118 "inform7/Chapter 22/Say Phrases.w"
;
}
#line 74 "inform7/Chapter 22/Say Phrases.w"
;
if (say_cs == IF_SAY_CS)
{
#line 123 "inform7/Chapter 22/Say 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 187 "inform7/Chapter 22/Say Phrases.w"
if (problem_issued == FALSE) {
Problems__sentence_problem(_P_(C22SayIfNested),
"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 128 "inform7/Chapter 22/Say Phrases.w"
;
}
#line 76 "inform7/Chapter 22/Say Phrases.w"
;
if ((say_cs == OTHERWISE_SAY_CS) || (say_cs == OTHERWISE_IF_SAY_CS))
{
#line 133 "inform7/Chapter 22/Say Phrases.w"
if (say_if_nesting == 0)
{
#line 202 "inform7/Chapter 22/Say Phrases.w"
if (problem_issued == FALSE) {
Problems__sentence_problem(_P_(C22SayOtherwiseWithoutIf),
"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 134 "inform7/Chapter 22/Say Phrases.w"
else if (SSP_sp > 0) {
if (SSP_stack[SSP_sp-1] != -1)
{
#line 213 "inform7/Chapter 22/Say Phrases.w"
if (problem_issued == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, inv->invocation_w1, inv->invocation_w2);
Problems__handmade_problem(_P_(C22ComplicatedSayStructure5));
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.");
Code__Phrases__add_say_construction_to_error(SSP_stack[SSP_sp-1]);
Problems__issue_problem_end();
problem_issued = TRUE;
}
}
#line 137 "inform7/Chapter 22/Say Phrases.w"
;
if (SSP_stack_otherwised[SSP_sp-1])
{
#line 229 "inform7/Chapter 22/Say Phrases.w"
if (problem_issued == FALSE) {
Problems__sentence_problem(_P_(C22TwoSayOtherwises),
"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 139 "inform7/Chapter 22/Say Phrases.w"
if (say_cs == OTHERWISE_SAY_CS) SSP_stack_otherwised[SSP_sp-1] = TRUE;
}
}
#line 78 "inform7/Chapter 22/Say Phrases.w"
;
if (say_cs == END_IF_SAY_CS)
{
#line 146 "inform7/Chapter 22/Say Phrases.w"
if (say_if_nesting == 0)
{
#line 240 "inform7/Chapter 22/Say Phrases.w"
if (problem_issued == FALSE) {
Problems__sentence_problem(_P_(C22SayEndIfWithoutSayIf),
"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 146 "inform7/Chapter 22/Say Phrases.w"
else if ((SSP_sp > 0) && (SSP_stack[SSP_sp-1] != -1))
{
#line 251 "inform7/Chapter 22/Say Phrases.w"
if (problem_issued == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, inv->invocation_w1, inv->invocation_w2);
Problems__handmade_problem(_P_(C22ComplicatedSayStructure4));
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.");
Code__Phrases__add_say_construction_to_error(SSP_stack[SSP_sp-1]);
Problems__issue_problem_end();
problem_issued = TRUE;
}
}
#line 148 "inform7/Chapter 22/Say Phrases.w"
else {
say_if_nesting--;
SSP_sp--;
}
}
#line 79 "inform7/Chapter 22/Say 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 266 "inform7/Chapter 22/Say Phrases.w"
if (problem_issued == FALSE) {
invocation *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_words(2, stinv->invocation_w1, stinv->invocation_w2);
Problems__handmade_problem(_P_(C22ComplicatedSayStructure3));
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) Code__Phrases__add_say_construction_to_error(ssp_tok);
Problems__issue_problem_end();
problem_issued = TRUE;
}
}
}
#line 88 "inform7/Chapter 22/Say Phrases.w"
;
}
}
it_is_not_worth_adding = it_was_not_worth_adding;
}
#line 41 "inform7/Chapter 22/Say Phrases.w"
;
return say_invocations_found;
}
#line 290 "inform7/Chapter 22/Say Phrases.w"
void Code__Phrases__add_say_construction_to_error(int ssp_tok) {
Problems__issue_problem_segment(" %P(The construction I'm thinking of is '");
add_scte_list(ssp_tok, SSP_START);
Problems__issue_problem_segment(" ... ");
add_scte_list(ssp_tok, SSP_MIDDLE);
Problems__issue_problem_segment(" ... ");
add_scte_list(ssp_tok, SSP_END);
Problems__issue_problem_segment("'.)");
}
void add_scte_list(int ssp_tok, int list_pos) {
phrase *ph; int ct = 0, w1, w2;
LOOP_OVER(ph, phrase)
if (Code__Phrases__TypeData__ssp_matches(&(ph->type_data),
ssp_tok, list_pos, &w1, &w2)) {
Problems__quote_words(3, w1, w2);
if (ct++ == 0) Problems__issue_problem_segment("[%3]");
else Problems__issue_problem_segment("/[%3]");
}
}
#line 323 "inform7/Chapter 22/Say Phrases.w"
void Code__SayPhrases__compile_invocation_group(OUTPUT_STREAM, invocation_group *invg, int stage) {
switch (stage) {
case -1: /* before the group is compiled */
if (Code__Invocations__get_group(invg->first_inv) == 0) {
if (Code__Invocations__Compiler__verify(invg->invl_in_question) > 0)
WRITE("say__p=1;"); /* warn the paragraph breaker: this will print */
}
{
#line 343 "inform7/Chapter 22/Say Phrases.w"
if (invg->first_in_next_group) {
if ((invg->first_in_next_group->say_verb) ||
(invg->first_in_next_group->say_adjective) ||
((Code__Phrases__TypeData__is_a_say_phrase(invg->first_in_next_group->phrase_invoked)) &&
(invg->first_in_next_group->phrase_invoked->type_data.as_say.say_phrase_running_on))) {
invocation *start = invg->first_inv;
INVOCATION_VARIABLE(look);
LOOP_THROUGH_INVOCATION_LIST(look, invg->invl_in_question) {
if (Code__Invocations__get_group(look) == Code__Invocations__get_group(start))
Code__Invocations__set_flag(look, SUPPRESS_IMPLIED_NEWLINES_INVFLAG);
}
}
}
}
#line 330 "inform7/Chapter 22/Say Phrases.w"
;
{
#line 360 "inform7/Chapter 22/Say Phrases.w"
if ((invg->first_inv->phrase_invoked) &&
(Code__Phrases__TypeData__is_a_say_phrase(invg->first_inv->phrase_invoked)) &&
(invg->first_inv->phrase_invoked->type_data.as_say.say_control_structure == NO_SAY_CS))
WRITE("ParaContent(); ");
}
#line 331 "inform7/Chapter 22/Say Phrases.w"
;
break;
case 1: /* after the group is compiled */
if (invg->first_in_next_group == NULL)
{
#line 383 "inform7/Chapter 22/Say Phrases.w"
WRITE(" .");
Formats__Inform6__Labels__write(OUT, "Say");
Formats__Inform6__Labels__Counters__read("Say", TRUE);
WRITE(";");
WRITE(" .");
Formats__Inform6__Labels__write(OUT, "SayX");
Formats__Inform6__Labels__Counters__read("SayX", TRUE);
WRITE(";");
if (Code__Invocations__test_flag(invg->first_inv, INSTEAD_INVFLAG))
WRITE(" rtrue;");
}
#line 335 "inform7/Chapter 22/Say Phrases.w"
;
break;
}
}
#line 33 "inform7/Chapter 22/Phrases as Values.w"
constant_phrase *Code__Phrases__Constants__create(int n1, int n2, int r1, int r2) {
constant_phrase *cphr = CREATE(constant_phrase);
cphr->word_ref1 = n1; cphr->word_ref2 = n2;
cphr->phrase_meant = NULL; /* we won't know until later */
cphr->cphr_kind = NULL; /* nor this */
cphr->cphr_form_w1 = r1; cphr->cphr_form_w2 = r2;
Semantics__Nouns__ExcerptMeanings__register(PHRASE_CONSTANT_MC, 0,
n1, n2, STORE_POINTER_constant_phrase(cphr));
return cphr;
}
#line 47 "inform7/Chapter 22/Phrases as Values.w"
constant_phrase *Code__Phrases__Constants__parse(int n1, int n2) {
if (parse_nt_against_word_range(spec_value_NTM, n1, n2, NULL, NULL)) {
specification *spec = most_recent_result_p;
if (Specifications__Values__is_CONSTANT_construction(spec, CON_phrase)) {
constant_phrase *cphr = MAP_spec_to_constant_phrase(spec);
Code__Phrases__Constants__kind(cphr);
return cphr;
}
}
return NULL;
}
#line 65 "inform7/Chapter 22/Phrases as Values.w"
kind *Code__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) {
int ow1 = -1, ow2 = -1;
ph_type_data phtd = Code__Phrases__TypeData__new();
Code__Phrases__TypeData__parse(
&phtd, cphr->cphr_form_w1, cphr->cphr_form_w2, &ow1, &ow2);
cphr->cphr_kind = Code__Phrases__TypeData__kind(&phtd);
}
return cphr->cphr_kind;
}
#line 81 "inform7/Chapter 22/Phrases as Values.w"
phrase *Code__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 22/Phrases as Values.w"
void Code__Phrases__Constants__compile(OUTPUT_STREAM, constant_phrase *cphr) {
phrase *ph = Code__Phrases__Constants__as_phrase(cphr);
if (ph == NULL) internal_error("cannot reconstruct phrase from cphr");
Code__Routines__ToPhrases__Requests__make(ph,
Code__Phrases__Constants__kind(cphr), NULL, -1, -1);
WRITE("Closure_%d", cphr->allocation_id);
}
#line 111 "inform7/Chapter 22/Phrases as Values.w"
void Code__Phrases__Constants__compile_closures(OUTPUT_STREAM) {
constant_phrase *cphr;
LOOP_OVER(cphr, constant_phrase) {
phrase *ph = Code__Phrases__Constants__as_phrase(cphr);
if (ph == NULL) internal_error("cannot reconstruct phrase from cphr");
Code__Phrases__Constants__kind(cphr);
{
#line 128 "inform7/Chapter 22/Phrases as Values.w"
WRITE("Array Closure_%d -->\n", cphr->allocation_id); INDENT;
Kinds__RuntimeIDs__compile_strong(OUT, cphr->cphr_kind);
WRITE(" ! "); Kinds__Textual__write(OUT, cphr->cphr_kind); WRITE("\n");
char identifier[32];
Code__Routines__ToPhrases__Requests__make_identifier(identifier, ph,
Code__Phrases__Constants__kind(cphr));
WRITE("%s ! routine to call\n", identifier);
WRITE("\""); Text__print_text_to_stream(cphr->word_ref1, cphr->word_ref2, OUT);
WRITE("\" ! name\n");
OUTDENT; WRITE(";\n");
}
#line 117 "inform7/Chapter 22/Phrases as Values.w"
;
}
}
#line 159 "inform7/Chapter 22/Phrases as Values.w"
int def_phrase_counter = 0;
void Code__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 177 "inform7/Chapter 22/Phrases as Values.w"
WRITE("Array %s -->\n", closure_identifier); INDENT;
Kinds__RuntimeIDs__compile_strong(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 166 "inform7/Chapter 22/Phrases as Values.w"
;
OUT = Code__Routines__begin(OUT, routine_identifier);
{
#line 190 "inform7/Chapter 22/Phrases as Values.w"
Code__LocalVariables__add_named_call("a");
Code__LocalVariables__add_named_call("b");
Code__LocalVariables__add_named_call("c");
Code__LocalVariables__add_named_call("d");
Code__LocalVariables__add_named_call("e");
Code__LocalVariables__add_named_call("f");
Code__LocalVariables__add_named_call("g");
Code__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__uses_pointer_values(result)) {
WRITE("BlkValueCreate(");
Kinds__RuntimeIDs__compile_strong(OUT, result);
WRITE(")");
} else {
if (Kinds__compile_default_value(OUT, result, -1, -1, NULL) != TRUE)
WRITE("false");
}
WRITE(";\n");
}
}
#line 169 "inform7/Chapter 22/Phrases as Values.w"
;
OUT = Code__Routines__end(OUT);
}
#line 27 "inform7/Chapter 22/Phrasebook Index.w"
void Code__Phrases__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, clue_w1 = -1, clue_w2 = -1;
phrase *ph, *run_begin = NULL;
LOOP_OVER(ph, phrase) {
/* include only if this is a To... phrase */
if (Code__Phrases__Usage__get_effect(&(ph->usage_data)) != TO_PHRASE_EFF)
continue;
/* and only if it is under an indexed heading */
heading *this_heading =
Parser__Sentences__Headings__heading_of(
Text__word_location(
Code__Phrases__declaration_node(ph)
->word_ref1));
if (Parser__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 =
Parser__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 72 "inform7/Chapter 22/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 56 "inform7/Chapter 22/Phrasebook Index.w"
;
if (this_heading != last_heading_named)
{
#line 91 "inform7/Chapter 22/Phrasebook Index.w"
int x1, x2;
Parser__Sentences__Headings__get_text(this_heading, &x1, &x2);
if (x1 >= 0) {
if (pass == 1)
{
#line 113 "inform7/Chapter 22/Phrasebook Index.w"
if (parse_nt_against_word_range(heading_with_parenthesis_NTM, x1, x2, NULL, NULL)) {
GET_RW(heading_with_parenthesis_NTM, 1, x1, x2);
}
}
#line 94 "inform7/Chapter 22/Phrasebook Index.w"
;
if (this_extension == standard_rules_extension)
{
#line 148 "inform7/Chapter 22/Phrasebook Index.w"
parse_nt_against_word_range(heading_name_hyphenated_NTM, x1, x2, NULL, NULL);
if (most_recent_result == 3) {
int c1, c2;
GET_RW(heading_name_hyphenated_NTM, 2, c1, c2);
if ((clue_w1 < 0) ||
(Text__compare_word_range(c1, c2, clue_w1, clue_w2) == FALSE)) {
clue_w1 = c1; clue_w2 = c2;
if (pass == 2) INDEX("<p><hr>");
INDEX("<p class=\"in1\"><b>");
Text__print_raw_text_to_stream(clue_w1, clue_w2, ifl);
INDEX("</b></p>");
no_subdivision_yet = TRUE;
}
GET_RW(heading_name_hyphenated_NTM, 3, x1, x2);
} else {
GET_RW(heading_name_hyphenated_NTM, 1, x1, x2);
}
}
#line 96 "inform7/Chapter 22/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 (x1 >= 0) Text__print_raw_text_to_stream(x1, x2, ifl);
else INDEX("Miscellaneous");
if (pass == 1) Index__below_link_numbered(ph->allocation_id);
if (pass == 2) INDEX("</b></p>");
no_subdivision_yet = FALSE;
}
#line 57 "inform7/Chapter 22/Phrasebook Index.w"
;
last_heading_named = this_heading;
last_extension_named = this_extension;
if (pass == 2)
{
#line 172 "inform7/Chapter 22/Phrasebook Index.w"
phrase *ph2 = ph, *run_end = ph;
if (ph_same_doc(ph, run_begin) == FALSE) run_begin = ph;
while ((ph2) && (ph_same_doc(ph, ph2))) {
run_end = ph2; ph2 = NEXT_OBJECT(ph2, phrase);
}
INDEX("<p class=\"tightin2\">");
if (run_begin == ph) Index__extra_link(ph->allocation_id);
else Index__noextra_link();
Code__Phrases__TypeData__write_index_representation(&(ph->type_data), ph);
if (Code__Phrases__TypeData__deprecated(&(ph->type_data)))
Index__deprecation_icon(run_begin->allocation_id);
Index__link(ph->declaration_node->word_ref1);
INDEX("</p>\n");
if (run_end == ph) {
Index__extra_div_open(ph->allocation_id, 3, "e0e0e0");
Code__Phrases__TypeData__write_reveal_box(&(run_begin->type_data), run_begin);
Index__extra_div_close("e0e0e0");
}
}
#line 61 "inform7/Chapter 22/Phrasebook Index.w"
;
}
}
}
}
#line 135 "inform7/Chapter 22/Phrasebook Index.w"
int heading_with_parenthesis_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 139 "inform7/Chapter 22/Phrasebook Index.w"
int heading_name_hyphenated_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 144 "inform7/Chapter 22/Phrasebook Index.w"
#line 198 "inform7/Chapter 22/Phrasebook Index.w"
int ph_same_doc(phrase *p1, phrase *p2) {
if ((p1 == NULL) || (p2 == NULL) ||
(p1->ph_documentation_symbol_wn < 0) || (p2->ph_documentation_symbol_wn < 0))
return FALSE;
if (strcmp(Text__word_raw_text(p1->ph_documentation_symbol_wn),
Text__word_raw_text(p2->ph_documentation_symbol_wn)) == 0) return TRUE;
return FALSE;
}
#line 211 "inform7/Chapter 22/Phrasebook Index.w"
void Code__Phrases__index_definition_area(int x1, int x2, int show_if_unhyphenated) {
parse_nt_against_word_range(heading_name_hyphenated_NTM, x1, x2, NULL, NULL);
if ((most_recent_result == 1) && (show_if_unhyphenated == FALSE)) return;
INDEX("<b>");
switch (most_recent_result) {
case 1: Text__print_raw_text_to_stream(x1, x2, ifl); break;
case 2: {
int c1, c2;
GET_RW(heading_name_hyphenated_NTM, 2, c1, c2);
Text__print_raw_text_to_stream(c1, c2, ifl); break;
}
case 3: {
int c1, c2, d1, d2;
GET_RW(heading_name_hyphenated_NTM, 2, c1, c2);
GET_RW(heading_name_hyphenated_NTM, 3, d1, d2);
Text__print_raw_text_to_stream(c1, c2, ifl);
INDEX(" - ");
Text__print_raw_text_to_stream(d1, d2, ifl);
break;
}
}
INDEX("</b><br>");
}
#line 52 "inform7/Chapter 22/Adjectival Definitions.w"
int definition_header_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 54 "inform7/Chapter 22/Adjectival Definitions.w"
#line 85 "inform7/Chapter 22/Adjectival Definitions.w"
int adjective_definition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 22/Adjectival Definitions.w"
int adjective_domain_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 22/Adjectival Definitions.w"
int adjective_wording_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 22/Adjectival Definitions.w"
#line 107 "inform7/Chapter 22/Adjectival Definitions.w"
void Code__Phrases__Adjectives__traverse(void) {
parse_node *p;
TREE_LOOP(p)
if (Parser__Nodes__type(p) == ROUTINE_NT)
if (parse_nt_against_word_range(definition_header_NTM, p->word_ref1, p->word_ref2, NULL, NULL)) {
parse_node *q = p->down;
if (q == NULL)
{
#line 134 "inform7/Chapter 22/Adjectival Definitions.w"
if ((p->next == NULL) ||
(Parser__Nodes__type(p->next) != ROUTINE_NT)) {
Problems__sentence_problem(_P_(BelievedImpossible),
"don't leave me in suspense",
"write a definition after 'Definition:'!");
continue;
}
q = p->next; p->next = q->next; p->down = q->down; q->next = NULL;
}
#line 113 "inform7/Chapter 22/Adjectival Definitions.w"
;
int dom_name_w1 = -1, dom_name_w2 = -1;
int called_w1 = -1, called_w2 = -1;
int adj_name_w1 = -1, adj_name_w2 = -1;
int neg_name_w1 = -1, neg_name_w2 = -1;
int cond_w1 = -1, cond_w2 = -1;
int the_format = DEFINED_IN_SOME_WAY_NOT_YET_KNOWN;
{
#line 146 "inform7/Chapter 22/Adjectival Definitions.w"
if (parse_nt_against_word_range(adjective_definition_NTM, q->word_ref1, q->word_ref2, NULL, NULL)) {
the_format = most_recent_result;
GET_RW(adjective_domain_NTM, 1, dom_name_w1, dom_name_w2);
if (calling_NTMV) GET_RW(adjective_domain_NTM, 2, called_w1, called_w2);
GET_RW(adjective_wording_NTM, 1, adj_name_w1, adj_name_w2);
if (antonym_NTMV) GET_RW(adjective_wording_NTM, 2, neg_name_w1, neg_name_w2);
if (the_format != DEFINED_PHRASALLY)
GET_RW(adjective_definition_NTM, 1, cond_w1, cond_w2);
}
}
#line 122 "inform7/Chapter 22/Adjectival Definitions.w"
;
{
#line 159 "inform7/Chapter 22/Adjectival Definitions.w"
if ((the_format == DEFINED_IN_SOME_WAY_NOT_YET_KNOWN) ||
((the_format == DEFINED_PHRASALLY) && (q->down == NULL))) {
LOG("Definition tree:\n$T\n", p);
Problems__definition_problem(_P_(C22DefinitionWithoutCondition),
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.");
continue;
}
if ((Text__mismatched_brackets(adj_name_w1, adj_name_w2)) ||
((neg_name_w1 >= 0) && (Text__mismatched_brackets(neg_name_w1, neg_name_w2)))) {
LOG("Definition tree:\n$T\n", p);
Problems__definition_problem(_P_(C22BracketedAdjective),
q, "this definition seems to involve unexpected brackets in the name of "
"the adjective being defined",
"so I think I must be misreading it.");
continue;
}
}
#line 123 "inform7/Chapter 22/Adjectival Definitions.w"
;
{
#line 182 "inform7/Chapter 22/Adjectival Definitions.w"
adjective_meaning *am =
Semantics__Adjectives__Meanings__parse(q, the_format, adj_name_w1, adj_name_w2,
dom_name_w1, dom_name_w2, cond_w1, cond_w2, called_w1, called_w2);
if (am == NULL) internal_error("unclaimed adjective definition");
if (neg_name_w1 >= 0) {
adjective_meaning *neg = Semantics__Adjectives__Meanings__negate(am);
Semantics__Adjectives__Meanings__declare(neg, neg_name_w1, neg_name_w2);
}
}
#line 124 "inform7/Chapter 22/Adjectival Definitions.w"
;
if (the_format != DEFINED_PHRASALLY) p->down = NULL;
}
}
#line 196 "inform7/Chapter 22/Adjectival Definitions.w"
definition *def_new(parse_node *q) {
definition *def = CREATE(definition);
def->node = q;
def->format = 0;
def->condition_w1 = -1; def->condition_w2 = -1;
def->domain_calling_w1 = -1; def->domain_calling_w2 = -1;
def->definition_node = current_sentence;
return def;
}
adjective_meaning *Code__Phrases__Adjectives__Condition__parse(parse_node *q,
int sense,
int adj_name_w1, int adj_name_w2,
int dom_name_w1, int dom_name_w2,
int cond_w1, int cond_w2,
int called_w1, int called_w2) {
if (sense == 0) return NULL;
definition *def = def_new(q);
adjective_meaning *am =
Semantics__Adjectives__Meanings__new(CONDITION_KADJ,
STORE_POINTER_definition(def), q->word_ref1, q->word_ref2);
def->condition_w1 = cond_w1; def->condition_w2 = cond_w2;
def->format = sense;
def->domain_calling_w1 = called_w1; def->domain_calling_w2 = called_w2;
def->am_of_def = am;
Semantics__Adjectives__Meanings__declare(am, adj_name_w1, adj_name_w2);
Semantics__Adjectives__Meanings__pass_task_to_support_routine(am, TEST_ADJECTIVE_TASK);
Semantics__Adjectives__Meanings__set_domain_from_word_range(am, dom_name_w1, dom_name_w2);
return am;
}
void Code__Phrases__Adjectives__Condition__compiling_soon(adjective_meaning *am,
definition *def, int T) {
}
int Code__Phrases__Adjectives__Condition__compile(definition *def, int T,
OUTPUT_STREAM, ph_stack_frame *phsf) {
switch (T) {
case TEST_ADJECTIVE_TASK:
if (OUT) {
Code__LocalVariables__Pronoun__alias(phsf,
def->domain_calling_w1, def->domain_calling_w2);
if (def->condition_w1 >= 0) {
current_sentence = def->node;
specification *spec = NULL;
if (parse_nt_against_word_range(spec_condition_NTM, def->condition_w1, def->condition_w2, NULL, NULL))
spec = most_recent_result_p;
if ((spec == NULL) ||
(Plugins__Actions__Patterns__validate_when(spec) == FALSE)) {
LOG("Error on: $W = $X", def->condition_w1, def->condition_w2, spec);
Problems__definition_problem(_P_(C22DefinitionBadCondition),
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__compile(OUT, spec);
if (def->format == -1) WRITE(")");
WRITE(")");
}
}
Code__LocalVariables__Pronoun__alias(phsf, -1, -1);
}
return TRUE;
case NOW_ADJECTIVE_TRUE_TASK:
return FALSE;
case NOW_ADJECTIVE_FALSE_TASK:
return FALSE;
}
return FALSE;
}
int Code__Phrases__Adjectives__Condition__assert(definition *def,
inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) {
LOG("Tried to assert def on $S\n", val_to_assert_on);
return FALSE;
}
int Code__Phrases__Adjectives__Condition__index(definition *def) {
return FALSE;
}
#line 286 "inform7/Chapter 22/Adjectival Definitions.w"
void Code__Phrases__Adjectives__define_by_phrase(parse_node *p, phrase *ph, int *cw1, int *cw2,
kind **K) {
definition *def;
*cw1 = -1; *cw2 = -1; *K = K_object;
if (ph == NULL) return;
LOOP_OVER(def, definition)
if ((def->definition_node == p) && (Semantics__Adjectives__Meanings__get_form(def->am_of_def) == PHRASE_KADJ)) {
i6_schema *sch = Semantics__Adjectives__Meanings__set_i6_schema(def->am_of_def, TEST_ADJECTIVE_TASK, FALSE);
Code__Schemas__modify(sch, "(%s(*1))", Code__Phrases__identifier(ph));
*cw1 = def->domain_calling_w1; *cw2 = def->domain_calling_w2;
*K = Semantics__Adjectives__Meanings__get_domain_forcing(def->am_of_def);
if ((*K == NULL) || (Kinds__le(*K, K_object)))
*K = K_object;
return;
}
}
adjective_meaning *Code__Phrases__Adjectives__Phrasal__parse(parse_node *q,
int sense,
int adj_name_w1, int adj_name_w2,
int dom_name_w1, int dom_name_w2,
int cond_w1, int cond_w2,
int called_w1, int called_w2) {
if (sense != 0) return NULL;
definition *def = def_new(q);
adjective_meaning *am = Semantics__Adjectives__Meanings__new(PHRASE_KADJ, STORE_POINTER_definition(def),
q->word_ref1, q->word_ref2);
def->domain_calling_w1 = called_w1; def->domain_calling_w2 = called_w2;
def->am_of_def = am;
Semantics__Adjectives__Meanings__declare(am, adj_name_w1, adj_name_w2);
Semantics__Adjectives__Meanings__pass_task_to_support_routine(am, TEST_ADJECTIVE_TASK);
Semantics__Adjectives__Meanings__set_domain_from_word_range(am, dom_name_w1, dom_name_w2);
return am;
}
void Code__Phrases__Adjectives__Phrasal__compiling_soon(adjective_meaning *am, definition *def, int T) {
}
int Code__Phrases__Adjectives__Phrasal__compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
int Code__Phrases__Adjectives__Phrasal__assert(definition *def,
inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) {
return FALSE;
}
int Code__Phrases__Adjectives__Phrasal__index(definition *def) {
return FALSE;
}
#line 343 "inform7/Chapter 22/Adjectival Definitions.w"
int inform6_routine_adjective_definition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 346 "inform7/Chapter 22/Adjectival Definitions.w"
#line 350 "inform7/Chapter 22/Adjectival Definitions.w"
adjective_meaning *Code__Phrases__Adjectives__RawPhrasal__parse(parse_node *q,
int sense,
int adj_name_w1, int adj_name_w2,
int dom_name_w1, int dom_name_w2,
int cond_w1, int cond_w2,
int called_w1, int called_w2) {
int explain_w1 = -1, explain_w2 = -1, rname_wn = -1, setting = FALSE;
if (parse_nt_against_word_range(inform6_routine_adjective_definition_NTM, cond_w1, cond_w2, NULL, NULL)) {
setting = most_recent_result;
GET_RW(inform6_routine_adjective_definition_NTM, 1, rname_wn, rname_wn);
GET_RW(inform6_routine_adjective_definition_NTM, 2, explain_w1, explain_w2);
} else return NULL;
if (sense != 1) return NULL;
if (called_w1 >= 0) return NULL;
Text__dequote_word(rname_wn);
definition *def = def_new(q);
adjective_meaning *am = Semantics__Adjectives__Meanings__new(I6_ROUTINE_KADJ, STORE_POINTER_definition(def),
explain_w1, explain_w2);
def->am_of_def = am;
Semantics__Adjectives__Meanings__declare(am, adj_name_w1, adj_name_w2);
Semantics__Adjectives__Meanings__set_domain_from_word_range(am, dom_name_w1, dom_name_w2);
if (setting) {
i6_schema *sch = Semantics__Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, TRUE);
Code__Schemas__modify(sch, "*=-(%s(*1, -1))", Text__word_text(rname_wn));
sch = Semantics__Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, TRUE);
Code__Schemas__modify(sch, "*=-(%s(*1, true))", Text__word_text(rname_wn));
sch = Semantics__Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_FALSE_TASK, TRUE);
Code__Schemas__modify(sch, "*=-(%s(*1, false))", Text__word_text(rname_wn));
} else {
Semantics__Adjectives__Meanings__pass_task_to_support_routine(am, TEST_ADJECTIVE_TASK);
i6_schema *sch = Semantics__Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, TRUE);
Code__Schemas__modify(sch, "*=-(%s(*1))", Text__word_text(rname_wn));
}
return am;
}
void Code__Phrases__Adjectives__RawPhrasal__compiling_soon(adjective_meaning *am, definition *def, int T) {
}
int Code__Phrases__Adjectives__RawPhrasal__compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
int Code__Phrases__Adjectives__RawPhrasal__assert(definition *def,
inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) {
return FALSE;
}
int Code__Phrases__Adjectives__RawPhrasal__index(definition *def) {
return FALSE;
}
#line 409 "inform7/Chapter 22/Adjectival Definitions.w"
int inform6_condition_adjective_definition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 411 "inform7/Chapter 22/Adjectival Definitions.w"
#line 415 "inform7/Chapter 22/Adjectival Definitions.w"
adjective_meaning *Code__Phrases__Adjectives__RawCondition__parse(parse_node *q,
int sense,
int adj_name_w1, int adj_name_w2,
int dom_name_w1, int dom_name_w2,
int cond_w1, int cond_w2,
int called_w1, int called_w2) {
if (sense != 1) return NULL;
if (called_w1 >= 0) return NULL;
if (!(parse_nt_against_word_range(inform6_condition_adjective_definition_NTM, cond_w1, cond_w2, NULL, NULL))) return NULL;
int text_wn = most_recent_result;
int inner1, inner2;
GET_RW(inform6_condition_adjective_definition_NTM, 1, inner1, inner2);
definition *def = def_new(q);
adjective_meaning *am =
Semantics__Adjectives__Meanings__new(I6_CONDITION_KADJ,
STORE_POINTER_definition(def), inner1, inner2);
def->am_of_def = am;
Semantics__Adjectives__Meanings__declare(am, adj_name_w1, adj_name_w2);
Semantics__Adjectives__Meanings__pass_task_to_support_routine(am, TEST_ADJECTIVE_TASK);
Semantics__Adjectives__Meanings__set_domain_from_word_range(am, dom_name_w1, dom_name_w2);
i6_schema *sch = Semantics__Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Text__dequote_word(text_wn);
Code__Schemas__modify(sch, "(%s)", Text__word_text(text_wn));
return am;
}
void Code__Phrases__Adjectives__RawCondition__compiling_soon(adjective_meaning *am, definition *def, int T) {
}
int Code__Phrases__Adjectives__RawCondition__compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
int Code__Phrases__Adjectives__RawCondition__assert(definition *def,
inference_subject *infs_to_assert_on, specification *val_to_assert_on, int parity) {
return FALSE;
}
int Code__Phrases__Adjectives__RawCondition__index(definition *def) {
return FALSE;
}
#line 37 "inform7/Chapter 22/Timed Phrases.w"
void Code__Phrases__Timed__TimedEventsTable_array(OUTPUT_STREAM) {
phrase *ph;
int i, t, when_count = 0;
WRITE("Array TimedEventsTable table");
LOOP_OVER(ph, phrase) {
t = Code__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", Code__Phrases__identifier(ph));
}
for (i=0; i<when_count+1; i++) WRITE(" 0 0");
WRITE(";\n");
}
void Code__Phrases__Timed__TimedEventTimesTable_array(OUTPUT_STREAM) {
phrase *ph;
int i, t, when_count = 0;
WRITE("Array TimedEventTimesTable table");
LOOP_OVER(ph, phrase) {
t = Code__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 22/Timed Phrases.w"
void Code__Phrases__Timed__note_usage(phrase *ph, parse_node *at) {
int t = Code__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 22/Timed Phrases.w"
void Code__Phrases__Timed__check_for_unused(void) {
phrase *ph;
LOOP_OVER(ph, phrase)
if (Code__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__sentence_problem(_P_(C22UnusedTimedEvent),
"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 22/Timed Phrases.w"
void Code__Phrases__Timed__index(void) {
int when_count = 0, tt_count = 0;
{
#line 115 "inform7/Chapter 22/Timed Phrases.w"
phrase *ph;
LOOP_OVER(ph, phrase) {
int t = Code__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\">");
Code__Phrases__Usage__index_preamble(&(ph->usage_data));
if ((ph->declaration_node != NULL) &&
(ph->declaration_node->word_ref1 >= 0))
Index__link(ph->declaration_node->word_ref1);
INDEX(" (where triggered: ");
use_as_event *uae;
for (uae = ph->usage_data.uses_as_event; uae; uae=uae->next)
Index__link(uae->where_triggered->word_ref1);
INDEX(")</p>");
}
}
}
#line 107 "inform7/Chapter 22/Timed Phrases.w"
;
{
#line 138 "inform7/Chapter 22/Timed Phrases.w"
phrase *ph;
LOOP_OVER(ph, phrase) {
int t = Code__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\">");
Code__Phrases__Usage__index_preamble(&(ph->usage_data));
if ((ph->declaration_node != NULL) &&
(ph->declaration_node->word_ref1 >= 0))
Index__link(ph->declaration_node->word_ref1);
INDEX("</p>");
}
}
}
#line 108 "inform7/Chapter 22/Timed Phrases.w"
;
if ((when_count == 0) && (tt_count == 0)) INDEX("<p><i>None.</i></p>");
}
#line 110 "inform7/Chapter 23/Rules.w"
rule *Code__Rules__new(int w1, int w2, int named) {
Text__Languages__remove_the(&w1, &w2);
rule *R = Code__Rules__by_name(w1, w2);
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->word_ref1 = w1; R->word_ref2 = w2;
R->italicised_text_w1 = -1; R->italicised_text_w2 = -1;
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_wn[l] = -1;
}
if (w1 >= 0) {
Code__Rules__vet_name(w1, w2);
{
#line 142 "inform7/Chapter 23/Rules.w"
general_pointer gp = STORE_POINTER_rule(R);
unsigned int mc = 0, smc = 0;
if (parse_nt_against_word_range(rule_name_formal_NTM, w1, w2, NULL, NULL)) {
mc = MISCELLANEOUS_MC; smc = RULE_SMC;
} else {
mc = RULE_MC;
}
Semantics__Nouns__ExcerptMeanings__register(mc, smc, w1, w2, gp);
}
#line 133 "inform7/Chapter 23/Rules.w"
;
}
return R;
}
#line 154 "inform7/Chapter 23/Rules.w"
rule *Code__Rules__by_name(int w1, int w2) {
if (w1 < 0) return NULL;
Text__Languages__remove_the(&w1, &w2);
if (parse_nt_against_word_range(rule_name_formal_NTM, w1, w2, NULL, NULL)) {
meaning_list *ml = Parser__SP__parse_excerpt(MISCELLANEOUS_MC, w1, w2);
if (ml) {
excerpt_meaning *em = Parser__SP__MeaningLists__meaning(ml);
if (Semantics__Nouns__ExcerptMeanings__get_secondary_code(em) == RULE_SMC)
return RETRIEVE_POINTER_rule(Semantics__Nouns__ExcerptMeanings__data(em));
}
} else {
meaning_list *ml = Parser__SP__parse_excerpt(RULE_MC, w1, w2);
if (ml) {
excerpt_meaning *em = Parser__SP__MeaningLists__meaning(ml);
return RETRIEVE_POINTER_rule(Semantics__Nouns__ExcerptMeanings__data(em));
}
}
return NULL;
}
#line 177 "inform7/Chapter 23/Rules.w"
int C22RuleWithComma_issued_at = -1;
void Code__Rules__vet_name(int w1, int w2) {
if (parse_nt_against_word_range(unsuitable_name_NTM, w1, w2, NULL, NULL)) {
if (C22RuleWithComma_issued_at != w1) {
C22RuleWithComma_issued_at = w1;
Problems__sentence_problem(_P_(C23RuleWithComma),
"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;
}
}
}
#line 197 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_I7_definition(rule *R, phrase *ph) {
R->defn_as_phrase = ph;
}
void Code__Rules__set_I6_definition(rule *R, char *identifier) {
strcpy(R->defn_as_I6_routine, identifier);
}
char *Code__Rules__get_I6_definition(rule *R) {
return R->defn_as_I6_routine;
}
phrase *Code__Rules__get_I7_definition(rule *R) {
if (R == NULL) return NULL;
return R->defn_as_phrase;
}
#line 217 "inform7/Chapter 23/Rules.w"
void Code__Rules__impose_constraint(rule *S, rule *R, int w1, int w2, int sense) {
applicability_condition *nac = CREATE(applicability_condition);
{
#line 226 "inform7/Chapter 23/Rules.w"
nac->word_ref1 = w1; nac->word_ref2 = w2;
nac->sense_of_applicability = sense;
nac->next_applicability_condition = NULL;
nac->where_imposed = current_sentence;
nac->substituted_rule = S;
}
#line 219 "inform7/Chapter 23/Rules.w"
;
{
#line 235 "inform7/Chapter 23/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 220 "inform7/Chapter 23/Rules.w"
;
}
#line 247 "inform7/Chapter 23/Rules.w"
void Code__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 260 "inform7/Chapter 23/Rules.w"
if (acl->word_ref1 == -1) {
WRITE("true");
} else {
if (parse_nt_against_word_range(spec_condition_NTM, acl->word_ref1, acl->word_ref2, NULL, NULL)) {
Specifications__compile(OUT, most_recent_result_p);
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, acl->word_ref1, acl->word_ref2);
Problems__handmade_problem(_P_(C23BadRuleConstraint));
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 251 "inform7/Chapter 23/Rules.w"
;
if (acl->sense_of_applicability) WRITE(")) "); else WRITE(") ");
{
#line 280 "inform7/Chapter 23/Rules.w"
if (acl->substituted_rule) {
WRITE("return ");
Code__Rules__compile(OUT, acl->substituted_rule);
WRITE("();\n");
} else {
WRITE("rfalse;\n");
}
}
#line 253 "inform7/Chapter 23/Rules.w"
;
}
}
#line 291 "inform7/Chapter 23/Rules.w"
void Code__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 306 "inform7/Chapter 23/Rules.w"
int Code__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 = Code__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 330 "inform7/Chapter 23/Rules.w"
int Code__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 350 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_kind_from(rule *R, rulebook *RB) {
kind *K = Code__Rulebooks__content_kind(RB);
if (R->kind_of_rule) {
if (Kinds__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_words(2, R->word_ref1, R->word_ref2);
Problems__quote_kind(3, B1);
Problems__quote_kind(4, P1);
Problems__quote_kind(5, B2);
Problems__quote_kind(6, P2);
Problems__quote_words_as_source(7,
R->kind_of_rule_set_from->word_ref1, R->kind_of_rule_set_from->word_ref2);
Problems__quote_words_as_source(8, RB->word_ref1, RB->word_ref2);
Problems__handmade_problem(_P_(C23RuleInIncompatibleRulebooks));
Problems__issue_problem_segment(
"The rule %2 now seems to be in two different rulebooks, which "
"is fine, but those rulebooks are of different kinds, which is "
"not. One is %7, which is based on %3 and produces %4; the "
"other is %8, which is based on %5 and produces %6.");
Problems__issue_problem_end();
}
}
R->kind_of_rule = K;
R->kind_of_rule_set_from = RB;
}
specification *Code__Rules__to_specification(rule *R) {
kind *K = R->kind_of_rule;
if (K == NULL) K = Kinds__binary_construction(CON_rule, K_action_name, K_nil);
specification *spec = Specifications__Values__new_actual_CONSTANT(K);
Specifications__set_structure_field(spec, STORE_POINTER_rule(R));
return spec;
}
rule *Code__Rules__from_specification(specification *spec) {
rule *R = RETRIEVE_POINTER_rule(Specifications__get_structure_field(spec));
if (R == NULL) internal_error("found NULL rule within RULE spec");
return R;
}
#line 396 "inform7/Chapter 23/Rules.w"
void Code__Rules__acquire_stvol(rule *R, stacked_variable_owner_list *stvol) {
R->listed_stv_owners =
Code__StackedVariables__Owners__Lists__append(R->listed_stv_owners, stvol);
}
void Code__Rules__acquire_action_variables(rule *R) {
Code__Rules__acquire_stvol(R, all_nonempty_stacked_action_vars);
if (all_action_processing_vars == NULL) internal_error("APROC not ready");
Code__Rules__acquire_stvol(R, all_action_processing_vars);
}
#line 425 "inform7/Chapter 23/Rules.w"
void Code__Rules__request_automatic_placement(rule *R) {
if (R->automatic_booking == NULL)
R->automatic_booking = Code__Rules__Bookings__new(R);
Code__Rules__Bookings__request_automatic_placement(R->automatic_booking);
}
#line 437 "inform7/Chapter 23/Rules.w"
void Code__Rules__compile(OUTPUT_STREAM, rule *R) {
if (R->defn_as_phrase) WRITE("%s", Code__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 451 "inform7/Chapter 23/Rules.w"
void Code__Rules__compile_rule_printing_switch(OUTPUT_STREAM) {
INDENT; INDENT;
rule *R;
LOOP_OVER(R, rule) {
if ((R->word_ref1 < 0) &&
((R->defn_as_phrase == NULL) ||
(R->defn_as_phrase->declaration_node == NULL) ||
(R->defn_as_phrase->declaration_node->down == NULL) ||
(R->defn_as_phrase->declaration_node->down->word_ref1 < 0)))
continue;
WRITE("if (R == "); Code__Rules__compile(OUT, R); WRITE(") { print \"");
{
#line 471 "inform7/Chapter 23/Rules.w"
if (R->word_ref1 >= 0) {
Formats__Inform6__compile_text_simply(OUT, R->word_ref1, R->word_ref2);
} else if (R->defn_as_phrase->declaration_node) {
int w1 = -1, w2 = -1;
w1 = R->defn_as_phrase->declaration_node->word_ref1; w2 = R->defn_as_phrase->declaration_node->word_ref2;
Text__Languages__remove_the(&w1, &w2);
Formats__Inform6__compile_text_simply(OUT, w1, w2);
} else Code__Rules__compile(OUT, R);
}
#line 462 "inform7/Chapter 23/Rules.w"
;
WRITE("\"; return; } ! rule %d\n", R->allocation_id);
}
OUTDENT; OUTDENT;
}
#line 483 "inform7/Chapter 23/Rules.w"
void Code__Rules__compile_comment(OUTPUT_STREAM, rule *R, int index, int from) {
if (R->defn_as_phrase) {
WRITE("! Rule %d/%d ", index, from);
Code__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 497 "inform7/Chapter 23/Rules.w"
void Code__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)
Code__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 520 "inform7/Chapter 23/Rules.w"
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "I6_Rule_Shell_%d", R->allocation_id);
OUT = Code__Routines__begin(OUT, i6_routine_identifier);
Code__Rules__compile_constraint(OUT, R->first_applicability_condition);
WRITE("return %s();\n", R->defn_as_I6_routine);
OUT = Code__Routines__end(OUT);
}
#line 505 "inform7/Chapter 23/Rules.w"
;
rule_being_compiled = NULL;
}
}
#line 534 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_italicised_index_text(rule *R, int w1, int w2) {
R->italicised_text_w1 = w1; R->italicised_text_w2 = w2;
}
#line 542 "inform7/Chapter 23/Rules.w"
int use_numbered_rules = FALSE;
void Code__Rules__set_numbered_rules(void) {
use_numbered_rules = TRUE;
}
#line 551 "inform7/Chapter 23/Rules.w"
int Code__Rules__index(rule *R, rulebook *owner, scene *during_scene) {
int no_responses_indexed = 0;
if (R->italicised_text_w1 >= 0)
{
#line 568 "inform7/Chapter 23/Rules.w"
INDEX("<i>");
Text__print_raw_text_to_stream(R->italicised_text_w1, R->italicised_text_w2, ifl);
if (during_scene) {
INDEX(" during ");
int s1 = -1, s2 = -1;
Plugins__Scenes__get_name(during_scene, &s1, &s2);
Text__print_raw_text_to_stream(s1, s2, ifl);
}
INDEX("</i>&nbsp;&nbsp;");
}
#line 553 "inform7/Chapter 23/Rules.w"
;
if (R->word_ref1 >= 0)
{
#line 583 "inform7/Chapter 23/Rules.w"
INDEX("<font color=\"#800000\">");
Text__print_raw_text_to_stream(R->word_ref1, R->word_ref2, ifl);
INDEX("</font>");
INDEX("&nbsp;&nbsp;");
char S[2*MAX_PASTEABLE_RULE_NAME_LENGTH + 50];
Text__print_raw_text_to_string_truncated(R->word_ref1, R->word_ref2, S,
MAX_PASTEABLE_RULE_NAME_LENGTH);
Formats__HTML__Javascript__paste(ifl, -1, -1, S);
INDEX("&nbsp;<i>name</i> ");
sprintf(S, "The ");
Text__print_text_to_string_truncated(R->word_ref1, R->word_ref2, S+Platform__strlen(S),
MAX_PASTEABLE_RULE_NAME_LENGTH);
sprintf(S+Platform__strlen(S), " is not listed in the ");
Text__print_text_to_string_truncated(owner->word_ref1, owner->word_ref2, S+Platform__strlen(S),
MAX_PASTEABLE_RULE_NAME_LENGTH);
sprintf(S+Platform__strlen(S), " rulebook.\n");
Formats__HTML__Javascript__paste(ifl, -1, -1, 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 554 "inform7/Chapter 23/Rules.w"
;
if ((R->italicised_text_w1 < 0) && (R->word_ref1 < 0) && (R->defn_as_phrase))
{
#line 633 "inform7/Chapter 23/Rules.w"
parse_node *pn = R->defn_as_phrase->declaration_node->down;
int w1 = -1, w2 = -1;
if (pn) { w1 = pn->word_ref1; w2 = pn->word_ref2; }
if (w1 >= 0) {
INDEX("(");
Text__print_raw_text_to_stream(w1, w2, ifl);
if (pn->next) INDEX("; ...");
INDEX(")");
}
}
#line 556 "inform7/Chapter 23/Rules.w"
;
{
#line 646 "inform7/Chapter 23/Rules.w"
if (R->defn_as_phrase) {
parse_node *pn = R->defn_as_phrase->declaration_node;
if ((pn) && (pn->word_ref1 >= 0)) Index__link(pn->word_ref1);
}
}
#line 557 "inform7/Chapter 23/Rules.w"
;
if (use_numbered_rules)
{
#line 654 "inform7/Chapter 23/Rules.w"
INDEX(" <small>");
if (R->defn_as_phrase) INDEX("%d", R->defn_as_phrase->allocation_id);
else INDEX("primitive");
INDEX("</small>");
}
#line 558 "inform7/Chapter 23/Rules.w"
;
{
#line 662 "inform7/Chapter 23/Rules.w"
applicability_condition *acl;
for (acl = R->first_applicability_condition; acl; acl = acl->next_applicability_condition) {
int w1 = acl->where_imposed->word_ref1, w2 = acl->where_imposed->word_ref2;
INDEX("<br>");
Index__link(w1);
INDEX("&nbsp;");
Text__print_raw_text_to_stream(w1, w2, ifl);
}
}
#line 559 "inform7/Chapter 23/Rules.w"
;
INDEX("</p>\n");
{
#line 619 "inform7/Chapter 23/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>");
Data__Strings__index_response(R, l, R->lettered_responses[l]);
c++;
}
if (c > 0) Index__extra_div_close_nested();
no_responses_indexed = c;
}
#line 561 "inform7/Chapter 23/Rules.w"
;
return no_responses_indexed;
}
#line 678 "inform7/Chapter 23/Rules.w"
void Code__Rules__set_always_test_actor(rule *R) {
if (R->defn_as_phrase) {
ph_runtime_context_data *phrcd = &(R->defn_as_phrase->runtime_context_data);
Code__Phrases__Context__set_always_test_actor(phrcd);
}
}
void Code__Rules__set_never_test_actor(rule *R) {
if (R->defn_as_phrase) {
ph_runtime_context_data *phrcd = &(R->defn_as_phrase->runtime_context_data);
Code__Phrases__Context__set_never_test_actor(phrcd);
}
}
void Code__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);
Code__Phrases__Context__set_marked_for_anyone(phrcd, to);
}
}
void Code__Rules__suppress_action_testing(rule *R) {
if (R->defn_as_phrase) {
ph_runtime_context_data *phrcd = &(R->defn_as_phrase->runtime_context_data);
Code__Phrases__Context__suppress_action_testing(phrcd);
}
}
void Code__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) ||
((Code__Phrases__Context__get_marked_for_anyone(phrcd_from)) &&
(Code__Phrases__Context__get_marked_for_anyone(phrcd_to) == FALSE))) {
Code__Phrases__Context__clear_always_test_actor(phrcd_to);
Code__Phrases__Context__set_never_test_actor(phrcd_to);
}
}
}
int Code__Rules__rule_is_named(rule *R) {
if (R == NULL) return FALSE;
return R->explicitly_named;
}
response_message *Code__Rules__rule_defines_response(rule *R, int code) {
if (R == NULL) return NULL;
if (code < 0) return NULL;
return R->lettered_responses[code];
}
void Code__Rules__check_response_usages(void) {
rule *R;
LOOP_OVER(R, rule) {
char offers[100];
offers[0] = 0;
int l, c;
for (l=0, c=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 (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_words(2, R->word_ref1, R->word_ref2);
Problems__quote_text(3, p);
if (c == 0) Problems__quote_text(4, "no lettered responses at all");
else Problems__quote_text(4, offers);
Problems__handmade_problem(_P_(C23NoSuchResponse));
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 Code__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 Code__Rules__now_rule_needs_response(rule *R, int code, int wn) {
if (R == NULL) internal_error("null rule uses response");
R->lettered_responses_used[code] = current_sentence;
if (wn >= 0) R->lettered_responses_value_wn[code] = wn;
}
int Code__Rules__get_response_wn(rule *R, int code) {
if (R == NULL) internal_error("null rule uses response");
return R->lettered_responses_value_wn[code];
}
parse_node *Code__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 *Code__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 23/Rule Bookings.w"
booking *Code__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 23/Rule Bookings.w"
void Code__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;
}
Code__Rules__log(br->rule_being_booked);
}
#line 83 "inform7/Chapter 23/Rule Bookings.w"
rule *Code__Rules__Bookings__get_rule(booking *br) {
if (br == NULL) return NULL;
return br->rule_being_booked;
}
#line 103 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__request_automatic_placement(booking *br) {
br->automatic_placement = TRUE;
}
#line 113 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__make_automatic_placements(void) {
booking *br;
LOOP_OVER(br, booking)
if (br->automatic_placement) {
phrase *ph = Code__Rules__get_I7_definition(br->rule_being_booked);
if (ph) {
current_sentence = ph->declaration_node;
Code__Phrases__Usage__place_in_rulebook(&(ph->usage_data), br);
Code__Rules__set_kind_from(br->rule_being_booked,
Code__Phrases__Usage__get_rulebook(&(ph->usage_data)));
}
}
}
#line 133 "inform7/Chapter 23/Rule Bookings.w"
void Code__Phrases__Usage__place_in_rulebook(ph_usage_data *phud, booking *br) {
if (Code__Phrases__Usage__get_effect(phud) == RULE_IN_RULEBOOK_EFF) {
rulebook *original_owner = Code__Phrases__Usage__get_rulebook(phud);
if (Code__Rulebooks__requires_specific_action(original_owner)) {
int waiver = FALSE;
action_name_list *anl;
action_name *an;
int w1 = -1, w2 = -1;
Code__Phrases__Usage__get_prewhile_text(phud, &w1, &w2);
if (w1 >= 0) {
int i;
for (i=w1; i<=w2; i++)
if (Plugins__Actions__Patterns__Named__by_name(i, w2))
goto NotSingleAction;
anl = Plugins__Actions__Lists__extract_actions_only(w1, w2);
an = Plugins__Actions__Lists__get_single_action(anl);
Code__Rules__set_marked_for_anyone(Code__Rules__Bookings__get_rule(br),
Plugins__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 = Plugins__Actions__longest_null(w1, w2, IS_TENSE, &x);
}
if ((an == NULL) && (waiver == FALSE)) {
NotSingleAction:
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C23MultipleCCR));
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]) {
Code__Phrases__Usage__set_rulebook(phud,
Plugins__Actions__get_fragmented_rulebook(an, built_in_rulebooks[CHECK_RB]));
} else if (original_owner == built_in_rulebooks[CARRY_OUT_RB]) {
Code__Phrases__Usage__set_rulebook(phud,
Plugins__Actions__get_fragmented_rulebook(an, built_in_rulebooks[CARRY_OUT_RB]));
} else if (original_owner == built_in_rulebooks[REPORT_RB]) {
Code__Phrases__Usage__set_rulebook(phud,
Plugins__Actions__get_fragmented_rulebook(an, built_in_rulebooks[REPORT_RB]));
} else {
Code__Phrases__Usage__set_rulebook(phud,
Plugins__Actions__switch_fragmented_rulebook(an, original_owner));
}
if (original_owner != Code__Phrases__Usage__get_rulebook(phud))
LOGIF(RULE_ATTACHMENTS, "Rerouting $b to $K\n", br,
Code__Phrases__Usage__get_rulebook(phud));
}
}
Code__Rulebooks__attach_rule(Code__Phrases__Usage__get_rulebook(phud), br,
Code__Phrases__Usage__get_rulebook_placement(phud), 0, NULL);
}
}
#line 212 "inform7/Chapter 23/Rule Bookings.w"
int 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 Code__Rules__compare_specificity(
br1->rule_being_booked, br2->rule_being_booked, log);
}
#line 247 "inform7/Chapter 23/Rule Bookings.w"
booking *Code__Rules__Bookings__list_new(void) {
return Code__Rules__Bookings__new(NULL);
}
#line 305 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_add(booking *list_head, booking *new_rule,
int placing, int side, rule *ref_rule) {
{
#line 318 "inform7/Chapter 23/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 307 "inform7/Chapter 23/Rule Bookings.w"
;
{
#line 338 "inform7/Chapter 23/Rule Bookings.w"
booking *pos, *prev;
for (prev=list_head, pos=list_head->next_rule; pos; prev=pos, pos=pos->next_rule)
if (Code__Rules__eq(Code__Rules__Bookings__get_rule(pos),
Code__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 308 "inform7/Chapter 23/Rule Bookings.w"
;
{
#line 353 "inform7/Chapter 23/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 (Code__Rules__eq(Code__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 309 "inform7/Chapter 23/Rule Bookings.w"
;
{
#line 367 "inform7/Chapter 23/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 310 "inform7/Chapter 23/Rule Bookings.w"
;
{
#line 378 "inform7/Chapter 23/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 311 "inform7/Chapter 23/Rule Bookings.w"
;
{
#line 390 "inform7/Chapter 23/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 404 "inform7/Chapter 23/Rule Bookings.w"
booking *pos;
switch(side) {
case BEFORE_SIDE:
for (pos=list_head->next_rule; pos; pos=pos->next_rule)
if (Code__Rules__eq(Code__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 (Code__Rules__eq(Code__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 392 "inform7/Chapter 23/Rule Bookings.w"
;
{
#line 423 "inform7/Chapter 23/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 393 "inform7/Chapter 23/Rule Bookings.w"
;
booking *insert_after = start_rule; /* insertion point is after this */
{
#line 435 "inform7/Chapter 23/Rule Bookings.w"
int log = FALSE; if (Log__Aspects__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 */
&& (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 395 "inform7/Chapter 23/Rule Bookings.w"
;
booking *subseq = insert_after->next_rule;
insert_after->next_rule = new_rule;
new_rule->next_rule = subseq;
{
#line 458 "inform7/Chapter 23/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 399 "inform7/Chapter 23/Rule Bookings.w"
;
}
#line 312 "inform7/Chapter 23/Rule Bookings.w"
;
}
#line 472 "inform7/Chapter 23/Rule Bookings.w"
void Code__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 (Code__Rules__eq(Code__Rules__Bookings__get_rule(br), ref_rule)) {
pr->next_rule = br->next_rule;
return;
}
}
}
#line 485 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_log(booking *list_head) {
if (list_head == NULL) { LOG("<null-booked-rule-list>\n"); return; }
int t = Code__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 499 "inform7/Chapter 23/Rule Bookings.w"
int Code__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 Code__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 = Code__Rules__get_I7_definition(br->rule_being_booked);
if ((ph) &&
(Code__Phrases__Context__get_scene(&(ph->runtime_context_data)) == S))
return FALSE;
}
return TRUE;
}
int Code__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 (Code__Rules__get_I7_definition(br->rule_being_booked))
return FALSE;
return TRUE;
}
int Code__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 (Code__Rules__eq(Code__Rules__Bookings__get_rule(br), to_find))
return TRUE;
return FALSE;
}
int Code__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 (Code__Rules__get_I7_definition(br->rule_being_booked) == ph_to_find)
return TRUE;
return FALSE;
}
#line 554 "inform7/Chapter 23/Rule Bookings.w"
int Code__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 = Code__Rules__get_I7_definition(R);
if (ph) {
ph_runtime_context_data *phrcd = &(ph->runtime_context_data);
scene *during_scene = Code__Phrases__Context__get_scene(phrcd);
if ((context) && (during_scene != context)) continue;
if ((action_context) &&
(Code__Phrases__Context__within_action_context(phrcd, action_context) == FALSE))
continue;
}
count++;
br_start_index_line(prev, billing);
*resp_count += Code__Rules__index(R, owner, context);
}
return count;
}
#line 581 "inform7/Chapter 23/Rule Bookings.w"
int show_index_links = TRUE;
void Code__Rules__Bookings__list_suppress_indexed_links(void) {
show_index_links = FALSE;
}
void Code__Rules__Bookings__list_resume_indexed_links(void) {
show_index_links = TRUE;
}
void br_start_index_line(booking *prev, char *billing) {
Formats__HTML__open_para(ifl, 2, "hanging");
if ((billing[0]) && (show_index_links)) br_show_linkage_icon(prev);
INDEX("%s", billing);
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;");
if ((billing[0] == 0) && (show_index_links)) br_show_linkage_icon(prev);
}
#line 602 "inform7/Chapter 23/Rule Bookings.w"
void 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)) {
Formats__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");
}
Formats__HTML__html_icon_with_tooltip(ifl, icon_name, prev->next_rule_specificity_law,
prev->next_rule_specificity_lawname);
}
#line 624 "inform7/Chapter 23/Rule Bookings.w"
void Code__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 643 "inform7/Chapter 23/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:
Code__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:
Code__Rules__Bookings__list_log(list_head);
internal_error("booking list invariant broken");
break;
}
break;
default:
Code__Rules__Bookings__list_log(list_head);
internal_error("booking list invariant broken");
break;
}
}
#line 630 "inform7/Chapter 23/Rule Bookings.w"
else
{
#line 685 "inform7/Chapter 23/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 = 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 632 "inform7/Chapter 23/Rule Bookings.w"
;
} else {
br->next_rule_specificity = 0;
br->next_rule_specificity_law = NULL;
}
}
}
#line 720 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_compile_rule_phrases(booking *list_head,
OUTPUT_STREAM, int *i, int max_i) {
if (list_head == NULL) return;
int t = Code__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++) {
Code__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;
}
}
}
}
Formats__Inform6__compile_divider_comment(OUT);
for (br = list_head->next_rule; br; br = br->next_rule)
Code__Rules__compile_definition(OUT, br->rule_being_booked, i, max_i);
}
#line 757 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__start_list_compilation(OUTPUT_STREAM) {
if (Code__Rulebooks__procedurals_exist()) {
WRITE("Constant PROCEDURAL_RULES_EXIST = true;\n");
WRITE("Array EMPTY_RULEBOOK -> $ff $ff $ff $ff;\n");
} else {
OUT = Code__Routines__begin(OUT, "EMPTY_RULEBOOK");
Code__LocalVariables__add_named_call("forbid_breaks");
WRITE("rfalse;\n");
OUT = Code__Routines__end(OUT);
}
}
#line 777 "inform7/Chapter 23/Rule Bookings.w"
void Code__Rules__Bookings__list_compile(booking *list_head, OUTPUT_STREAM,
char *identifier, int action_based, int parameter_based) {
if (list_head == NULL) return;
int countup = Code__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 (Code__Rulebooks__procedurals_exist() == FALSE)
format = ROUTINE_RBF;
{
#line 800 "inform7/Chapter 23/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 836 "inform7/Chapter 23/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 = Code__Routines__begin(OUT, identifier);
Code__LocalVariables__add_named_call("forbid_breaks");
Code__LocalVariables__add_internal_local_c("rv", "return value");
if (countup > 1)
Code__LocalVariables__add_internal_local_c("original_deadflag", "saved state");
if (parameter_based)
Code__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 807 "inform7/Chapter 23/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) {
specification *spec = Code__Rules__to_specification(br->rule_being_booked);
if (grouping) {
if (group_size == 0) {
if (group_started)
{
#line 899 "inform7/Chapter 23/Rule Bookings.w"
if (action_group_open) {
switch (format) {
case ROUTINE_RBF: OUTDENT; WRITE("} else {\n"); INDENT;
{
#line 925 "inform7/Chapter 23/Rule Bookings.w"
if (entry_count > 0) WRITE("if (say__p) RulebookParBreak(forbid_breaks);\n");
}
#line 902 "inform7/Chapter 23/Rule Bookings.w"
;
OUTDENT; WRITE("}\n"); break;
}
action_group_open = FALSE;
}
}
#line 814 "inform7/Chapter 23/Rule Bookings.w"
;
action_name *an = br_required_action(br);
booking *brg = br;
while ((brg) && (an == br_required_action(brg))) {
group_size++;
brg = brg->next_rule;
}
if (group_size > group_cap) group_size = group_cap;
group_started = TRUE;
{
#line 856 "inform7/Chapter 23/Rule Bookings.w"
switch (format) {
case GROUPED_ARRAY_RBF:
if (an) WRITE(" ##%s", Plugins__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", Plugins__Actions__identifier(an));
INDENT;
action_group_open = TRUE;
}
break;
}
}
#line 823 "inform7/Chapter 23/Rule Bookings.w"
;
}
group_size--;
}
{
#line 875 "inform7/Chapter 23/Rule Bookings.w"
switch (format) {
case ARRAY_RBF:
case GROUPED_ARRAY_RBF:
WRITE(" "); Specifications__compile(OUT, spec);
break;
case ROUTINE_RBF:
if (entry_count > 0) WRITE("if (original_deadflag ~= deadflag) return 0;\n");
{
#line 925 "inform7/Chapter 23/Rule Bookings.w"
if (entry_count > 0) WRITE("if (say__p) RulebookParBreak(forbid_breaks);\n");
}
#line 882 "inform7/Chapter 23/Rule Bookings.w"
;
if (parameter_based) WRITE("parameter_value = p;\n");
WRITE("rv = "); Specifications__compile(OUT, spec);
WRITE("();\n");
WRITE("if (rv) {\n"); INDENT;
WRITE("if (rv == 2) return reason_the_action_failed;\n");
WRITE("return ");
Specifications__compile(OUT, spec);
WRITE(";\n");
OUTDENT; WRITE("}\n");
WRITE("latest_rule_result-->0 = 0;\n");
break;
}
}
#line 827 "inform7/Chapter 23/Rule Bookings.w"
;
entry_count++;
}
if (group_started)
{
#line 899 "inform7/Chapter 23/Rule Bookings.w"
if (action_group_open) {
switch (format) {
case ROUTINE_RBF: OUTDENT; WRITE("} else {\n"); INDENT;
{
#line 925 "inform7/Chapter 23/Rule Bookings.w"
if (entry_count > 0) WRITE("if (say__p) RulebookParBreak(forbid_breaks);\n");
}
#line 902 "inform7/Chapter 23/Rule Bookings.w"
;
OUTDENT; WRITE("}\n"); break;
}
action_group_open = FALSE;
}
}
#line 830 "inform7/Chapter 23/Rule Bookings.w"
;
{
#line 911 "inform7/Chapter 23/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 = Code__Routines__end(OUT);
break;
}
}
#line 831 "inform7/Chapter 23/Rule Bookings.w"
;
}
#line 792 "inform7/Chapter 23/Rule Bookings.w"
;
}
#line 931 "inform7/Chapter 23/Rule Bookings.w"
action_name *br_required_action(booking *br) {
phrase *ph = Code__Rules__get_I7_definition(br->rule_being_booked);
if (ph) return Code__Phrases__Context__required_action(&(ph->runtime_context_data));
return NULL;
}
#line 160 "inform7/Chapter 23/Rulebooks.w"
int new_rulebook_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 23/Rulebooks.w"
Problems__sentence_problem(_P_(C23RulebookWithAt),
"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 23/Rulebooks.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 183 "inform7/Chapter 23/Rulebooks.w"
Problems__sentence_problem(_P_(C23RulebookWithTo),
"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 23/Rulebooks.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 195 "inform7/Chapter 23/Rulebooks.w"
Problems__sentence_problem(_P_(C23RulebookWithDefinition),
"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 23/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 23/Rulebooks.w"
#line 209 "inform7/Chapter 23/Rulebooks.w"
int rulebook_name_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 212 "inform7/Chapter 23/Rulebooks.w"
#line 222 "inform7/Chapter 23/Rulebooks.w"
rulebook *Code__Rulebooks__new(kind *create_as, int w1, int w2) {
rulebook *rb = CREATE(rulebook);
parse_nt_against_word_range(new_rulebook_name_NTM, w1, w2, NULL, NULL);
GET_RW(new_rulebook_name_NTM, 1, w1, w2);
rb->word_ref1 = w1; rb->word_ref2 = w2;
rb->alt_word_ref1 = -1; rb->alt_word_ref2 = -1;
Semantics__Nouns__ExcerptMeanings__register(RULEBOOK_MC, 0, w1, w2,
STORE_POINTER_rulebook(rb));
Semantics__Nouns__ExcerptMeanings__register_assemblage(RULEBOOK_MC, 0,
Text__Languages__merge(rulebook_name_construction_NTM, 0,
Text__Words__from_range(w1, w2)),
STORE_POINTER_rulebook(rb));
Semantics__Nouns__ExcerptMeanings__register_assemblage(RULEBOOK_MC, 0,
Text__Languages__merge(rulebook_name_construction_NTM, 1,
Text__Words__from_range(w1, w2)),
STORE_POINTER_rulebook(rb));
Formats__Inform6__compose_identifier(rb->rb_I6_identifier, 'B', rb->allocation_id, w1, w2);
rb->rule_list = Code__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);
Code__Rulebooks__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;
Code__Rulebooks__initialise_outcomes(&(rb->my_outcomes), producing_kind, def);
rb->placement_list = NULL;
rb->owned_by_rb = Code__StackedVariables__Owners__new(rb->allocation_id);
rb->accessible_from_rb = Code__StackedVariables__Owners__Lists__add_owner(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 = Code__StackedVariables__Owners__Lists__add_owner(NULL, rb->owned_by_rb);
return rb;
}
outcomes *Code__Rulebooks__get_outcomes(rulebook *rb) {
return &(rb->my_outcomes);
}
specification *Code__Rulebooks__to_specification(rulebook *rb) {
kind *K = Kinds__binary_construction(CON_rulebook,
Code__Rulebooks__get_parameter_kind(rb), Code__Rulebooks__get_outcome_kind(&(rb->my_outcomes)));
specification *spec = Specifications__Values__new_actual_CONSTANT(K);
Specifications__set_structure_field(spec, STORE_POINTER_rulebook(rb));
return spec;
}
kind *Code__Rulebooks__content_kind(rulebook *rb) {
return Kinds__binary_construction(CON_rule,
Code__Rulebooks__get_parameter_kind(rb),
Code__Rulebooks__get_outcome_kind(&(rb->my_outcomes)));
}
rulebook *Code__Rulebooks__from_specification(specification *spec) {
if (!(Specifications__Values__is_actual_CONSTANT_construction(spec, CON_rulebook))) {
LOG("Bad spec is: $S\n", spec);
internal_error("tried to find rulebook inside SP of wrong type");
}
rulebook *rb = RETRIEVE_POINTER_rulebook(Specifications__get_structure_field(spec));
if (rb == NULL) internal_error("found NULL rulebook within RULEBOOK spec");
return rb;
}
rulebook *Code__Rulebooks__new_automatic(int w1, int w2, kind *basis,
int oc, int ata, int ubfaa, int rda) {
rulebook *rb = Code__Rulebooks__new(
Kinds__binary_construction(CON_rulebook, basis, K_nil),
w1, w2);
Code__Rulebooks__set_default_outcome(&(rb->my_outcomes), oc);
Code__Rulebooks__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 Code__Rulebooks__set_alt_name(rulebook *rb, int aw1, int aw2) {
rb->alt_word_ref1 = aw1; rb->alt_word_ref2 = aw2;
Semantics__Nouns__ExcerptMeanings__register(RULEBOOK_MC, 0, aw1, aw2,
STORE_POINTER_rulebook(rb));
}
void Code__Rulebooks__fragment_by_actions(rulebook *rb, int wn) {
rb->fragmentation_stem_length = wn;
}
int Code__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 338 "inform7/Chapter 23/Rulebooks.w"
void Code__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 rb_no_placements(rulebook *rb) {
int t = 0;
placement_affecting *npl = rb->placement_list;
while (npl) { t++; npl = npl->next; }
return t;
}
void rb_index_placements(rulebook *rb) {
placement_affecting *npl = rb->placement_list;
while (npl) {
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<small><i>NB:</i> ");
Text__print_text_to_stream(npl->placement_sentence->word_ref1, npl->placement_sentence->word_ref2, ifl);
Index__link(npl->placement_sentence->word_ref1);
INDEX("</small><br>\n");
npl = npl->next;
}
}
#line 367 "inform7/Chapter 23/Rulebooks.w"
int Code__Rulebooks__focus(rulebook *rb) {
return Code__Rulebooks__get_focus(&(rb->my_focus));
}
kind *Code__Rulebooks__get_parameter_kind(rulebook *rb) {
return Code__Rulebooks__get_focus_parameter_kind(&(rb->my_focus));
}
int Code__Rulebooks__used_by_future_actions(rulebook *rb) {
return rb->used_by_future_action_activity;
}
int Code__Rulebooks__is_empty(rulebook *rb, scene *context) {
if (rb == NULL) return TRUE;
return Code__Rules__Bookings__list_is_empty(rb->rule_list, context);
}
int Code__Rulebooks__no_rules(rulebook *rb) {
if (rb == NULL) return 0;
return Code__Rules__Bookings__no_rules_in_list(rb->rule_list);
}
int Code__Rulebooks__rule_in_rulebook(rule *R, rulebook *rb) {
if (rb == NULL) return FALSE;
return Code__Rules__Bookings__list_contains(rb->rule_list, R);
}
booking *Code__Rulebooks__first_booking(rulebook *rb) {
if (rb == NULL) return NULL;
return rb->rule_list;
}
int Code__Rulebooks__runs_during_activities(rulebook *rb) {
return rb->runs_during_activities;
}
#line 407 "inform7/Chapter 23/Rulebooks.w"
int rulebook_variable_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 414 "inform7/Chapter 23/Rulebooks.w"
*X = NOT_APPLICABLE;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C23RulebookVariableAnd));
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 408 "inform7/Chapter 23/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 410 "inform7/Chapter 23/Rulebooks.w"
#line 429 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__add_variable(rulebook *rb, parse_node *cnode) {
specification *spec;
int nw1, nw2, tw1, tw2;
if (Parser__Nodes__type(cnode) != PROPERTYCALLED_NT) {
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C23RulebookVarUncalled));
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;
}
tw1 = cnode->down->word_ref1; tw2 = cnode->down->word_ref2;
nw1 = cnode->down->next->word_ref1; nw2 = cnode->down->next->word_ref2;
if (parse_nt_against_word_range(rulebook_variable_name_NTM, nw1, nw2, NULL, NULL)) {
if (most_recent_result == NOT_APPLICABLE) return;
}
spec = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, tw1, tw2, NULL, NULL)) spec = most_recent_result_p;
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
if ((Specifications__Conditions__get_described_kind(spec)) &&
(Specifications__Conditions__number_of_adjectives_applied_to(spec) == 0)) {
spec = Specifications__Values__new_generic_CONSTANT(
Specifications__Conditions__get_described_kind(spec));
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, tw1, tw2);
Problems__handmade_problem(_P_(C23RulebookVariableTooSpecific));
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 (Specifications__Values__is_actual_CONSTANT(spec)) {
LOG("Offending SP: $X", spec);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, tw1, tw2);
Problems__handmade_problem(_P_(C23RulebookVariableBadKind));
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__eq(Specifications__get_kind(spec), K_value)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, tw1, tw2);
Problems__handmade_problem(_P_(C23RulebookVariableVague));
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;
}
Code__StackedVariables__Owners__add(rb->owned_by_rb, nw1, nw2,
Specifications__get_kind(spec));
}
void Code__Rulebooks__make_stvs_accessible(rulebook *rb, stacked_variable_owner *stvo) {
rb->accessible_from_rb = Code__StackedVariables__Owners__Lists__add_owner(rb->accessible_from_rb, stvo);
}
void Code__Rulebooks__rulebook_var_creators_array(OUTPUT_STREAM) {
rulebook *rb;
WRITE("#IFNDEF MEMORY_ECONOMY;\n");
WRITE("Array rulebook_var_creators -->");
LOOP_OVER(rb, rulebook) {
if (Code__StackedVariables__Owners__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 (Code__StackedVariables__Owners__empty(rb->owned_by_rb) == FALSE)
Code__StackedVariables__Owners__compile_frame_creator(OUT, rb->owned_by_rb,
" RBSTVC_%d", rb->allocation_id);
}
}
void Code__Rulebooks__rulebook_var_creators_lookup(OUTPUT_STREAM) {
rulebook *rb;
WRITE("#ifdef MEMORY_ECONOMY;\n");
WRITE("switch (rb) {\n");
LOOP_OVER(rb, rulebook)
if (Code__StackedVariables__Owners__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 545 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__log_name_only(rulebook *rb) {
LOG("Rulebook %d ($W)", rb->allocation_id, rb->word_ref1, rb->word_ref2);
}
void Code__Rulebooks__log(rulebook *rb) {
Code__Rulebooks__log_name_only(rb);
LOG(": ");
Code__Rules__Bookings__list_log(rb->rule_list);
}
int Code__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) || (Code__Rules__Bookings__list_is_empty(rb->rule_list, context)))
suppress_outcome = TRUE;
}
t = Code__Rules__Bookings__list_index(rb->rule_list, context, action_context,
billing, rb, resp_count);
Code__Rulebooks__index_outcomes(&(rb->my_outcomes), suppress_outcome);
rb_index_placements(rb);
return t;
}
void Code__Rulebooks__index_action_rules(action_name *an, rulebook *rb,
int code, char *desc, int *resp_count) {
int t = 0;
Code__Rules__Bookings__list_suppress_indexed_links();
if (code >= 0) t += Code__Rulebooks__index(built_in_rulebooks[code], desc,
NULL, an, resp_count);
if (rb) t += Code__Rulebooks__index(rb, desc, NULL, NULL, resp_count);
Code__Rules__Bookings__list_resume_indexed_links();
if (t > 0) INDEX("<br>");
}
#line 593 "inform7/Chapter 23/Rulebooks.w"
int rulebook_stem_NTMR(int w1, int w2, int *X, void **XP) {
#line 594 "inform7/Chapter 23/Rulebooks.w"
rulebook_match rm = rb_match_from_description(w1, w2);
if (rm.matched_rulebook == NULL) return FALSE;
parsed_rm = rm;
return w1 + rm.advance_words - 1;
}
#line 621 "inform7/Chapter 23/Rulebooks.w"
int rulebook_stem_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 625 "inform7/Chapter 23/Rulebooks.w"
int rulebook_stem_inner_unarticled_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = LAST_PLACEMENT; len_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *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 632 "inform7/Chapter 23/Rulebooks.w"
int rulebook_stem_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 637 "inform7/Chapter 23/Rulebooks.w"
#line 641 "inform7/Chapter 23/Rulebooks.w"
rulebook_match rb_match_from_description(int w1, int w2) {
int initial_w1 = w1, modifier_words;
int art = NO_ART, pl = MIDDLE_PLACEMENT;
rulebook *rb;
rulebook_match rm;
parse_nt_against_word_range(rulebook_stem_inner_NTM, w1, w2, NULL, NULL);
GET_RW(rulebook_stem_name_NTM, 1, w1, w2);
art = most_recent_result; pl = place_NTMV;
modifier_words = w1 - 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 {
int x1 = rb->word_ref1, x2 = rb->word_ref2;
if (w2-w1 >= x2-x1) {
int this_match = x2-x1+1;
if (Text__compare_word_range(x1, x2, w1, w1+x2-x1) == FALSE) goto TryAlt;
if (rm.match_length < this_match) {
rm.match_length = this_match;
rm.matched_rulebook = rb;
}
}
TryAlt: x1 = rb->alt_word_ref1; x2 = rb->alt_word_ref2;
if (x1 < 0) continue;
if (w2-w1 >= x2-x1) {
int this_match = x2-x1+1;
if (Text__compare_word_range(x1, x2, w1, w1+x2-x1) == FALSE) continue;
if (rm.match_length < this_match) {
rm.match_length = this_match;
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 = w1 + rm.match_length - 1;
if (w1a != w2)
rm.match_length = rm.matched_rulebook->fragmentation_stem_length;
}
rm.match_length += modifier_words;
rm.advance_words += modifier_words;
return rm;
}
#line 731 "inform7/Chapter 23/Rulebooks.w"
void Code__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 (Code__Rules__Bookings__get_rule(the_new_rule) == ref_rule) {
if (side != INSTEAD_SIDE)
Problems__sentence_problem(_P_(C23BeforeOrAfterSelf),
"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 = Code__Rules__get_I7_definition(Code__Rules__Bookings__get_rule(the_new_rule));
if (ph) {
action_name *an = Code__Phrases__Context__required_action(&(ph->runtime_context_data));
if ((an) && (Plugins__Actions__is_out_of_world(an)))
Problems__sentence_problem(_P_(C23OOWinIWRulebook),
"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]) {
Code__Rules__set_never_test_actor(Code__Rules__Bookings__get_rule(the_new_rule));
} else {
Code__Rulebooks__modify_rule_to_suit_focus(&(rb->my_focus),
Code__Rules__Bookings__get_rule(the_new_rule));
}
if (side == INSTEAD_SIDE) {
LOGIF(RULE_ATTACHMENTS,
"Copying actor test flags from rule being replaced\n");
Code__Rules__copy_actor_test_flags(Code__Rules__Bookings__get_rule(the_new_rule), ref_rule);
LOGIF(RULE_ATTACHMENTS,
"Copying former rulebook's variable permissions to displaced rule\n");
Code__Rules__acquire_stvol(ref_rule, rb->accessible_from_rb);
if (Code__Rulebooks__focus(rb) == ACTION_FOCUS)
Code__Rules__acquire_action_variables(ref_rule);
}
Code__Rules__acquire_stvol(Code__Rules__Bookings__get_rule(the_new_rule), rb->accessible_from_rb);
if (Code__Rulebooks__focus(rb) == ACTION_FOCUS)
Code__Rules__acquire_action_variables(Code__Rules__Bookings__get_rule(the_new_rule));
if (rb->fragmentation_stem_length > 0)
Code__Rules__suppress_action_testing(Code__Rules__Bookings__get_rule(the_new_rule));
Code__Phrases__Context__ensure_avl(Code__Rules__Bookings__get_rule(the_new_rule));
Code__Rules__Bookings__list_add(rb->rule_list, the_new_rule, placing, side, ref_rule);
LOGIF(RULE_ATTACHMENTS, "Rulebook after attachment: $K", rb);
}
void Code__Rulebooks__detach_rule(rulebook *rb, rule *the_new_rule) {
Code__Rules__Bookings__list_remove(rb->rule_list, the_new_rule);
}
#line 801 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__compile_rule_phrases(rulebook *rb, OUTPUT_STREAM, int *i, int max_i) {
Code__Rules__Bookings__list_judge_ordering(rb->rule_list);
if (Code__Rules__Bookings__list_is_empty_of_i7_rules(rb->rule_list)) return;
WRITE("\n");
Formats__Inform6__compile_divider_comment(OUT);
WRITE("! Rules in rulebook: ");
Text__print_raw_text_within_i6_literal(OUT, rb->word_ref1, rb->word_ref2);
WRITE(" (%s)\n", rb->rb_I6_identifier);
Formats__Inform6__compile_divider_comment(OUT);
Code__Rules__Bookings__list_compile_rule_phrases(rb->rule_list, OUT, i, max_i);
Formats__Inform6__compile_divider_comment(OUT);
}
void Code__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 Code__Rulebooks__procedurals_exist(void) {
return FALSE;
}
void Code__Rulebooks__compile_rulebooks(OUTPUT_STREAM) {
Code__Rules__Bookings__start_list_compilation(OUT);
rulebook *rb;
LOOP_OVER(rb, rulebook) {
int act = FALSE;
if (Code__Rulebooks__focus(rb) == ACTION_FOCUS) act = TRUE;
if (rb->automatically_generated) act = FALSE;
int par = FALSE;
if (Code__Rulebooks__focus(rb) == PARAMETER_FOCUS) par = TRUE;
LOGIF(RULEBOOK_COMPILATION, "Compiling rulebook: $W = %s\n",
rb->word_ref1, rb->word_ref2, rb->rb_I6_identifier);
Code__Rules__Bookings__list_compile(rb->rule_list, OUT, rb->rb_I6_identifier, act, par);
}
}
void Code__Rulebooks__RulebookNames_array(OUTPUT_STREAM) {
rulebook *rb;
WRITE("Array RulebookNames -->\n"); INDENT;
LOOP_OVER(rb, rulebook) {
WRITE("\"");
Text__print_raw_text_within_i6_literal(OUT, rb->word_ref1, rb->word_ref2);
WRITE(" rulebook\" ! %d\n", rb->allocation_id);
}
OUTDENT; WRITE(";\n\n");
}
#line 863 "inform7/Chapter 23/Rulebooks.w"
int rulebook_property_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 871 "inform7/Chapter 23/Rulebooks.w"
*X = NOT_APPLICABLE;
Problems__sentence_problem(_P_(C23NonOutcomeProperty),
"the only properties of a rulebook are its outcomes",
"for the time being at least.");
}
#line 866 "inform7/Chapter 23/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 867 "inform7/Chapter 23/Rulebooks.w"
#line 879 "inform7/Chapter 23/Rulebooks.w"
outcomes *outcomes_being_parsed = NULL;
void Code__Rulebooks__parse_properties(rulebook *rb, int w1, int w2) {
outcomes_being_parsed = &(rb->my_outcomes);
parse_nt_against_word_range(rulebook_property_NTM, w1, w2, NULL, NULL);
}
kind *Code__Rulebooks__kind_from_context(void) {
phrase *ph = phrase_being_compiled;
rulebook *rb;
if (ph == NULL) return NULL;
LOOP_OVER(rb, rulebook)
if (Code__Rules__Bookings__list_contains_ph(rb->rule_list, ph))
return Code__Rulebooks__get_outcome_kind(&(rb->my_outcomes));
return NULL;
}
#line 901 "inform7/Chapter 23/Rulebooks.w"
void Code__Rulebooks__index_page(int n) {
if (n == 1) {
{
#line 985 "inform7/Chapter 23/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>");
Code__Rulebooks__index_rules_box("Persuasion", -1, -1, "rules_per",
built_in_rulebooks[PERSUASION_RB], NULL, NULL, 1, TRUE);
Code__Rulebooks__index_rules_box("Unsuccessful attempt by", -1, -1, "rules_fail",
built_in_rulebooks[UNSUCCESSFUL_ATTEMPT_BY_RB], NULL, NULL, 1, TRUE);
Code__Rulebooks__index_rules_box("Before", -1, -1, "rules_before",
built_in_rulebooks[BEFORE_RB], NULL, NULL, 1, TRUE);
Code__Rulebooks__index_rules_box("Instead", -1, -1, "rules_instead",
built_in_rulebooks[INSTEAD_RB], NULL, NULL, 1, TRUE);
Code__Rulebooks__index_rules_box("Check", -1, -1, 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);
Code__Rulebooks__index_rules_box("Carry out", -1, -1, NULL, NULL, NULL,
"Carry out rules are tied to specific actions, and there are too many "
"to index here.", 1, TRUE);
Code__Rulebooks__index_rules_box("After", -1, -1, "rules_after",
built_in_rulebooks[AFTER_RB], NULL, NULL, 1, TRUE);
Code__Rulebooks__index_rules_box("Report", -1, -1, NULL, NULL, NULL,
"Report rules are tied to specific actions, and there are too many "
"to index here.", 1, TRUE);
}
#line 903 "inform7/Chapter 23/Rulebooks.w"
;
{
#line 947 "inform7/Chapter 23/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>");
Code__Rulebooks__index_rules_box("When play begins", -1, -1, "rules_wpb",
built_in_rulebooks[WHEN_PLAY_BEGINS_RB], NULL, NULL, 1, TRUE);
Code__Rulebooks__index_rules_box("Every turn", -1, -1, "rules_et",
built_in_rulebooks[EVERY_TURN_RB], NULL, NULL, 1, TRUE);
Code__Rulebooks__index_rules_box("When play ends", -1, -1, "rules_wpe",
built_in_rulebooks[WHEN_PLAY_ENDS_RB], NULL, NULL, 1, TRUE);
}
#line 904 "inform7/Chapter 23/Rulebooks.w"
;
{
#line 964 "inform7/Chapter 23/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>");
Code__Rulebooks__index_rules_box("Does the player mean", -1, -1, "rules_dtpm",
built_in_rulebooks[DOES_THE_PLAYER_MEAN_RB], NULL, NULL, 1, TRUE);
Code__Activities__index_by_number(READING_A_COMMAND_ACT, 1);
Code__Activities__index_by_number(DECIDING_SCOPE_ACT, 1);
Code__Activities__index_by_number(DECIDING_CONCEALED_POSSESS_ACT, 1);
Code__Activities__index_by_number(DECIDING_WHETHER_ALL_INC_ACT, 1);
Code__Activities__index_by_number(CLARIFYING_PARSERS_CHOICE_ACT, 1);
Code__Activities__index_by_number(ASKING_WHICH_DO_YOU_MEAN_ACT, 1);
Code__Activities__index_by_number(PRINTING_A_PARSER_ERROR_ACT, 1);
Code__Activities__index_by_number(SUPPLYING_A_MISSING_NOUN_ACT, 1);
Code__Activities__index_by_number(SUPPLYING_A_MISSING_SECOND_ACT, 1);
Code__Activities__index_by_number(IMPLICITLY_TAKING_ACT, 1);
}
#line 905 "inform7/Chapter 23/Rulebooks.w"
;
{
#line 1058 "inform7/Chapter 23/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>");
Code__Activities__index_by_number(PRINTING_THE_NAME_ACT, 1);
Code__Activities__index_by_number(PRINTING_THE_PLURAL_NAME_ACT, 1);
Code__Activities__index_by_number(PRINTING_A_NUMBER_OF_ACT, 1);
Code__Activities__index_by_number(PRINTING_ROOM_DESC_DETAILS_ACT, 1);
Code__Activities__index_by_number(PRINTING_INVENTORY_DETAILS_ACT, 1);
Code__Activities__index_by_number(LISTING_CONTENTS_ACT, 1);
Code__Activities__index_by_number(GROUPING_TOGETHER_ACT, 1);
Code__Activities__index_by_number(WRITING_A_PARAGRAPH_ABOUT_ACT, 1);
Code__Activities__index_by_number(LISTING_NONDESCRIPT_ITEMS_ACT, 1);
Code__Activities__index_by_number(PRINTING_LOCALE_DESCRIPTION_ACT, 1);
Code__Activities__index_by_number(CHOOSING_NOTABLE_LOCALE_OBJ_ACT, 1);
Code__Activities__index_by_number(PRINTING_LOCALE_PARAGRAPH_ACT, 1);
}
#line 906 "inform7/Chapter 23/Rulebooks.w"
;
{
#line 1034 "inform7/Chapter 23/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>");
Code__Rulebooks__index_rules_box("Reaching inside", -1, -1, "rules_ri",
built_in_rulebooks[REACHING_INSIDE_RB], NULL, NULL, 1, TRUE);
Code__Rulebooks__index_rules_box("Reaching outside", -1, -1, "rules_ri",
built_in_rulebooks[REACHING_OUTSIDE_RB], NULL, NULL, 1, TRUE);
Code__Rulebooks__index_rules_box("Visibility", -1, -1, "visibility",
built_in_rulebooks[VISIBILITY_RB], NULL, NULL, 1, TRUE);
}
#line 907 "inform7/Chapter 23/Rulebooks.w"
;
{
#line 1047 "inform7/Chapter 23/Rulebooks.w"
INDEX("<p><b>Light and darkness</b></p>");
INDEX("<p>These activities control how we describe darkness.</p>");
Code__Activities__index_by_number(PRINTING_NAME_OF_DARK_ROOM_ACT, 1);
Code__Activities__index_by_number(PRINTING_DESC_OF_DARK_ROOM_ACT, 1);
Code__Activities__index_by_number(PRINTING_NEWS_OF_DARKNESS_ACT, 1);
Code__Activities__index_by_number(PRINTING_NEWS_OF_LIGHT_ACT, 1);
Code__Activities__index_by_number(REFUSAL_TO_ACT_IN_DARK_ACT, 1);
}
#line 908 "inform7/Chapter 23/Rulebooks.w"
;
{
#line 926 "inform7/Chapter 23/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>");
Code__Rulebooks__index_rules_box("Startup rules", -1, -1, NULL,
built_in_rulebooks[STARTUP_RB], NULL, NULL, 1, TRUE);
Code__Activities__index_by_number(STARTING_VIRTUAL_MACHINE_ACT, 2);
Code__Activities__index_by_number(PRINTING_BANNER_TEXT_ACT, 2);
Code__Rulebooks__index_rules_box("Turn sequence rules", -1, -1, NULL,
built_in_rulebooks[TURN_SEQUENCE_RB], NULL, NULL, 1, TRUE);
Code__Activities__index_by_number(CONSTRUCTING_STATUS_LINE_ACT, 2);
Code__Rulebooks__index_rules_box("Shutdown rules", -1, -1, NULL,
built_in_rulebooks[SHUTDOWN_RB], NULL, NULL, 1, TRUE);
Code__Activities__index_by_number(AMUSING_A_VICTORIOUS_PLAYER_ACT, 2);
Code__Activities__index_by_number(PRINTING_PLAYERS_OBITUARY_ACT, 2);
Code__Activities__index_by_number(DEALING_WITH_FINAL_QUESTION_ACT, 2);
}
#line 909 "inform7/Chapter 23/Rulebooks.w"
;
{
#line 1013 "inform7/Chapter 23/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>");
Code__Rulebooks__index_rules_box("Action-processing rules", -1, -1, NULL,
built_in_rulebooks[ACTION_PROCESSING_RB], NULL, NULL, 1, TRUE);
Code__Rulebooks__index_rules_box("Specific action-processing rules", -1, -1, NULL,
built_in_rulebooks[SPECIFIC_ACTION_PROCESSING_RB], NULL, NULL, 2, TRUE);
Code__Rulebooks__index_rules_box("Player's action awareness rules", -1, -1, NULL,
built_in_rulebooks[PLAYERS_ACTION_AWARENESS_RB], NULL, NULL, 3, TRUE);
}
#line 910 "inform7/Chapter 23/Rulebooks.w"
;
{
#line 1026 "inform7/Chapter 23/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>");
Code__Activities__index_by_number(PRINTING_RESPONSE_ACT, 1);
}
#line 911 "inform7/Chapter 23/Rulebooks.w"
;
} else {
if (noteworthy_rulebooks(NULL) > 0)
{
#line 1077 "inform7/Chapter 23/Rulebooks.w"
INDEX("<p><b>From the source text</b></p>");
extension_file *ef = NULL; /* that is, not in an extension at all */
{
#line 1092 "inform7/Chapter 23/Rulebooks.w"
activity *av;
rulebook *rb;
LOOP_OVER(rb, rulebook) {
source_file *sf = Text__file_of_origin(rb->word_ref1);
if (rb->automatically_generated) continue;
if (((ef == NULL) && (sf == NULL)) ||
(Text__Reader__sf_get_extension_corresponding(sf) == ef))
Code__Rulebooks__index_rules_box(NULL, rb->word_ref1, rb->word_ref2, NULL, rb, NULL, NULL, 1, TRUE);
}
LOOP_OVER(av, activity) {
source_file *sf = Text__file_of_origin(av->word_ref1);
if (((ef == NULL) && (sf == NULL)) ||
(Text__Reader__sf_get_extension_corresponding(sf) == ef))
Code__Activities__index(av, 1);
}
}
#line 1079 "inform7/Chapter 23/Rulebooks.w"
;
}
#line 914 "inform7/Chapter 23/Rulebooks.w"
;
extension_file *ef;
LOOP_OVER(ef, extension_file)
if (ef != standard_rules_extension)
if (noteworthy_rulebooks(ef) > 0)
{
#line 1084 "inform7/Chapter 23/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 1092 "inform7/Chapter 23/Rulebooks.w"
activity *av;
rulebook *rb;
LOOP_OVER(rb, rulebook) {
source_file *sf = Text__file_of_origin(rb->word_ref1);
if (rb->automatically_generated) continue;
if (((ef == NULL) && (sf == NULL)) ||
(Text__Reader__sf_get_extension_corresponding(sf) == ef))
Code__Rulebooks__index_rules_box(NULL, rb->word_ref1, rb->word_ref2, NULL, rb, NULL, NULL, 1, TRUE);
}
LOOP_OVER(av, activity) {
source_file *sf = Text__file_of_origin(av->word_ref1);
if (((ef == NULL) && (sf == NULL)) ||
(Text__Reader__sf_get_extension_corresponding(sf) == ef))
Code__Activities__index(av, 1);
}
}
#line 1087 "inform7/Chapter 23/Rulebooks.w"
;
}
#line 919 "inform7/Chapter 23/Rulebooks.w"
;
}
}
#line 1111 "inform7/Chapter 23/Rulebooks.w"
int noteworthy_rulebooks(extension_file *ef) {
int nb = 0;
activity *av;
rulebook *rb;
LOOP_OVER(rb, rulebook) {
source_file *sf = Text__file_of_origin(rb->word_ref1);
if (rb->automatically_generated) continue;
if (((ef == NULL) && (sf == NULL)) ||
(Text__Reader__sf_get_extension_corresponding(sf) == ef)) nb++;
}
LOOP_OVER(av, activity) {
source_file *sf = Text__file_of_origin(av->word_ref1);
if (((ef == NULL) && (sf == NULL)) ||
(Text__Reader__sf_get_extension_corresponding(sf) == ef)) nb++;
}
return nb;
}
void Code__Rulebooks__index_scene(void) {
INDEX("<p><b>The scene-changing machinery</b><p>");
Code__Rulebooks__index_rules_box("Scene changing", -1, -1, NULL, built_in_rulebooks[SCENE_CHANGING_RB], NULL, NULL, 1, FALSE);
}
int unique_xtra_no = 0;
void Code__Rulebooks__index_rules_box(char *name, int w1, int w2, 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 = Code__Rulebooks__no_rules(rb);
if (av) n = Code__Activities__no_rules(av);
char textual_name[600];
if (name) strcpy(textual_name, name);
else if (w1 >= 0) Text__print_raw_text_to_string_truncated(w1, w2, textual_name, 500);
else strcpy(textual_name, "nameless");
textual_name[0] = Platform__tolower(textual_name[0]);
if (hide_behind_plus) {
Formats__HTML__open_para(ifl, indent+1, "tight");
Index__extra_link(xtra_no);
if (n == 0) INDEX("<font color=\"#808080\">");
INDEX("%s", textual_name);
{
#line 1225 "inform7/Chapter 23/Rulebooks.w"
if (doc_link) Index__doc_link(doc_link);
INDEX(" ... ");
if (av) INDEX(" activity"); else {
if ((rb) && (Code__Rulebooks__get_parameter_kind(rb)) &&
(Kinds__eq(Code__Rulebooks__get_parameter_kind(rb), K_action_name) == FALSE)) {
INDEX(" ");
Kinds__Textual__write_articled(ifl, Code__Rulebooks__get_parameter_kind(rb));
INDEX(" based");
}
INDEX(" rulebook");
}
int wn = -1;
if (rb) wn = rb->word_ref1; else if (av) wn = av->word_ref1;
if (wn >= 0) Index__link(wn);
}
#line 1160 "inform7/Chapter 23/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 {
Formats__HTML__open_para(ifl, indent, "");
Formats__HTML__open_coloured_box(ifl, col, ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
}
Formats__HTML__begin_html_table(ifl, NULL, TRUE, 0, 4, 0, 0, 0);
Formats__HTML__first_html_column(ifl, 0);
Formats__HTML__open_para(ifl, 1, "tight");
INDEX("<b>%s</b>", textual_name);
{
#line 1225 "inform7/Chapter 23/Rulebooks.w"
if (doc_link) Index__doc_link(doc_link);
INDEX(" ... ");
if (av) INDEX(" activity"); else {
if ((rb) && (Code__Rulebooks__get_parameter_kind(rb)) &&
(Kinds__eq(Code__Rulebooks__get_parameter_kind(rb), K_action_name) == FALSE)) {
INDEX(" ");
Kinds__Textual__write_articled(ifl, Code__Rulebooks__get_parameter_kind(rb));
INDEX(" based");
}
INDEX(" rulebook");
}
int wn = -1;
if (rb) wn = rb->word_ref1; else if (av) wn = av->word_ref1;
if (wn >= 0) Index__link(wn);
}
#line 1177 "inform7/Chapter 23/Rulebooks.w"
;
INDEX("</p>");
Formats__HTML__next_html_column_right_justified(ifl, 0);
Formats__HTML__open_para(ifl, 1, "tight");
if (av) {
char skeleton[600];
sprintf(skeleton, "Before %s:", textual_name);
Formats__HTML__Javascript__paste(ifl, -1, -1, skeleton);
INDEX("&nbsp;<i>b</i> ");
sprintf(skeleton, "Rule for %s:", textual_name);
Formats__HTML__Javascript__paste(ifl, -1, -1, skeleton);
INDEX("&nbsp;<i>f</i> ");
sprintf(skeleton, "After %s:", textual_name);
Formats__HTML__Javascript__paste(ifl, -1, -1, skeleton);
INDEX("&nbsp;<i>a</i>");
} else {
Formats__HTML__Javascript__paste(ifl, -1, -1, textual_name);
INDEX("&nbsp;<i>name</i>");
}
INDEX("</p>");
Formats__HTML__end_html_row(ifl);
Formats__HTML__end_html_table(ifl);
if ((rb) && (Code__Rulebooks__is_empty(rb, NULL))) text = "There are no rules in this rulebook.";
if (text) {
Formats__HTML__open_para(ifl, 2, "tight");
INDEX("%s</p>", text);
} else {
if (rb) {
int ignore_me = 0;
Code__Rulebooks__index(rb, "", NULL, NULL, &ignore_me);
}
if (av) Code__Activities__index_details(av);
}
if (hide_behind_plus) {
Index__extra_div_close(col);
} else {
Formats__HTML__close_coloured_box(ifl, col, ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
INDEX("</p>");
}
}
#line 90 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__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 Code__Rulebooks__set_default_outcome(outcomes *outs, int def) {
outs->default_rule_outcome = def;
}
kind *Code__Rulebooks__get_outcome_kind(outcomes *outs) {
return outs->value_outcome_kind;
}
#line 110 "inform7/Chapter 23/Focus and Outcome.w"
int rulebook_default_outcome_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 122 "inform7/Chapter 23/Focus and Outcome.w"
if (outcomes_being_parsed->default_outcome_declared) {
Problems__sentence_problem(_P_(C23DefaultOutcomeTwice),
"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 23/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 23/Focus and Outcome.w"
Problems__sentence_problem(_P_(C23BadDefaultOutcome),
"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 23/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 23/Focus and Outcome.w"
int rule_outcome_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 23/Focus and Outcome.w"
#line 142 "inform7/Chapter 23/Focus and Outcome.w"
int default_rbno_flag = FALSE;
#line 153 "inform7/Chapter 23/Focus and Outcome.w"
int rulebook_outcome_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 23/Focus and Outcome.w"
int rulebook_outcome_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 23/Focus and Outcome.w"
int rulebook_outcome_setting_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; if (!preform_lookahead_mode)
{
#line 183 "inform7/Chapter 23/Focus and Outcome.w"
int o1, o2;
GET_RW(form_of_named_rule_outcome_NTM, 1, o1, o2);
int def = FALSE;
if (default_rbno_flag) {
if (outcomes_being_parsed->default_named_outcome) {
Problems__sentence_problem(_P_(C23DefaultNamedOutcomeTwice),
"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__sentence_problem(_P_(C23DefaultOutcomeAlready),
"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 = rbno_by_name(o1, o2);
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__sentence_problem(_P_(C23DuplicateOutcome),
"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 23/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 23/Focus and Outcome.w"
int form_of_named_rule_outcome_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 23/Focus and Outcome.w"
*X = UNRECOGNISED_OUTCOME;
Problems__sentence_problem(_P_(C23BadOutcomeClarification),
"the bracketed clarification isn't what I expected",
"which would be one of '(success)', '(failure)' or '(no outcome)'.");
}
#line 169 "inform7/Chapter 23/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 23/Focus and Outcome.w"
#line 230 "inform7/Chapter 23/Focus and Outcome.w"
named_rulebook_outcome *rbno_by_name(int w1, int w2) {
named_rulebook_outcome *rbno;
meaning_list *ml = Parser__SP__parse_excerpt(MISCELLANEOUS_MC, w1, w2);
if ((ml != NULL) && (Semantics__Nouns__ExcerptMeanings__get_secondary_code(Parser__SP__MeaningLists__meaning(ml)) == RULE_OUTCOME_SMC)) {
return RETRIEVE_POINTER_named_rulebook_outcome(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
}
rbno = CREATE(named_rulebook_outcome);
Semantics__Nouns__ExcerptMeanings__register(
MISCELLANEOUS_MC, RULE_OUTCOME_SMC, w1, w2,
STORE_POINTER_named_rulebook_outcome(rbno));
rbno->word_ref1 = w1;
rbno->word_ref2 = w2;
return rbno;
}
void Code__Rulebooks__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__RuntimeIDs__weak(K_rulebook_outcome),
rbo->outcome_name->allocation_id);
break;
case FAILURE_OUTCOME:
WRITE("RulebookFails(%d, RBNO_%d); rtrue;\n",
Kinds__RuntimeIDs__weak(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 *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 = Code__Rulebooks__get_outcomes(rb);
rulebook_outcome *ro;
for (ro = outs->named_outcomes; ro; ro = ro->next) {
if (ro->outcome_name == rbno) {
if (Code__Rules__Bookings__list_contains_ph(Code__Rulebooks__first_booking(rb), ph))
return ro;
}
}
}
return NULL;
}
rulebook *Code__Rulebooks__allow_outcome(named_rulebook_outcome *rbno) {
if (Code__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 = Code__Rulebooks__get_outcomes(rb);
if (Code__Rules__Bookings__list_contains_ph(Code__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 Code__Rulebooks__compile_outcome(OUTPUT_STREAM, named_rulebook_outcome *rbno) {
rulebook_outcome *rbo = rbo_from_context(rbno);
if (rbo == NULL) {
rulebook *rb;
LOOP_OVER(rb, rulebook) {
outcomes *outs = Code__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__RuntimeIDs__weak(K_rulebook_outcome),
rbno->allocation_id);
break;
case FAILURE_OUTCOME:
WRITE("RulebookFails(%d, RBNO_%d); rtrue;\n",
Kinds__RuntimeIDs__weak(K_rulebook_outcome),
rbno->allocation_id);
break;
case NO_OUTCOME:
WRITE("rfalse;\n");
break;
default:
internal_error("bad RBO outcome kind");
}
}
void Code__Rulebooks__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;
Formats__HTML__open_para(ifl, 2, "hanging");
INDEX("<i>outcome</i>&nbsp;&nbsp;");
if (outs->default_named_outcome == ro) INDEX("<b>");
Text__print_raw_text_to_stream(rbno->word_ref1, rbno->word_ref2, ifl);
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)) {
Formats__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 Code__Rulebooks__RulebookOutcomePrintingRule_routine(OUTPUT_STREAM) {
named_rulebook_outcome *rbno;
LOOP_OVER(rbno, named_rulebook_outcome) {
WRITE("Constant RBNO_%d = \"", rbno->allocation_id);
Text__print_raw_text_to_stream(rbno->word_ref1, rbno->word_ref2, OUT);
WRITE("\";\n");
}
OUT = Code__Routines__begin(OUT, "RulebookOutcomePrintingRule");
Code__LocalVariables__add_named_call("rbno");
WRITE("if (rbno == 0) print \"(no outcome)\";\n");
WRITE("else print (string) rbno; rfalse;\n");
OUT = Code__Routines__end(OUT);
}
char default_value_of_rulebook_outcome_kind[16];
char *Code__Rulebooks__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 403 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__initialise_focus(focus *foc, kind *parameter_kind) {
foc->rules_always_test_actor = FALSE;
int parametrisation = PARAMETER_FOCUS;
if (Kinds__eq(parameter_kind, K_action_name)) parametrisation = ACTION_FOCUS;
foc->kind_of_parameter = parameter_kind;
foc->rulebook_focus = parametrisation;
}
#line 416 "inform7/Chapter 23/Focus and Outcome.w"
void Code__Rulebooks__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");
Code__Rules__set_always_test_actor(R);
}
if (foc->rulebook_focus == PARAMETER_FOCUS){
LOGIF(RULE_ATTACHMENTS,
"Setting never test actor for destination rulebook\n");
Code__Rules__set_never_test_actor(R);
}
}
int Code__Rulebooks__get_focus(focus *foc) {
return foc->rulebook_focus;
}
kind *Code__Rulebooks__get_focus_parameter_kind(focus *foc) {
return foc->kind_of_parameter;
}
void Code__Rulebooks__set_focus_ata(focus *foc, int ata) {
foc->rules_always_test_actor = ata;
}
#line 17 "inform7/Chapter 23/Rule Placement Sentences.w"
void Code__Rules__declare_I6_written_rule(int w1, int w2, parse_node *p2) {
char *I6_name = Text__word_text(p2->word_ref1);
rule *R = Code__Rules__new(w1, w2, TRUE);
Code__Rules__set_I6_definition(R, I6_name);
}
#line 28 "inform7/Chapter 23/Rule Placement Sentences.w"
int rulebook_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 29 "inform7/Chapter 23/Rule Placement Sentences.w"
Text__Languages__remove_the(&w1, &w2);
meaning_list *ml = Parser__SP__parse_excerpt(RULEBOOK_MC, w1, w2);
if (ml) {
*XP = RETRIEVE_POINTER_rulebook(
Semantics__Nouns__ExcerptMeanings__data(
Parser__SP__MeaningLists__meaning(ml)));
return TRUE;
}
return FALSE;
}
int rule_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 41 "inform7/Chapter 23/Rule Placement Sentences.w"
Text__Languages__remove_the(&w1, &w2);
rule *R = Code__Rules__by_name(w1, w2);
if (R) {
*XP = R;
return TRUE;
}
return FALSE;
}
#line 63 "inform7/Chapter 23/Rule Placement Sentences.w"
int substitutes_for_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 74 "inform7/Chapter 23/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C23NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 65 "inform7/Chapter 23/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 66 "inform7/Chapter 23/Rule Placement Sentences.w"
int substitutes_for_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 74 "inform7/Chapter 23/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C23NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 69 "inform7/Chapter 23/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 70 "inform7/Chapter 23/Rule Placement Sentences.w"
#line 85 "inform7/Chapter 23/Rule Placement Sentences.w"
void Code__Rules__request_substitute(parse_node *p1, parse_node *p2, parse_node *p3,
int sense) {
parse_nt_against_word_range(substitutes_for_sentence_subject_NTM, p1->word_ref1, p1->word_ref2, NULL, NULL);
if (most_recent_result == FALSE) return;
rule *new_rule = most_recent_result_p;
parse_nt_against_word_range(substitutes_for_sentence_object_NTM, p2->word_ref1, p2->word_ref2, NULL, NULL);
if (most_recent_result == FALSE) return;
rule *old_rule = most_recent_result_p;
int c1 = -1, c2 = -1;
if (p3) { c1 = p3->word_ref1; c2 = p3->word_ref2; }
Code__Rules__impose_constraint(new_rule, old_rule, c1, c2, (sense)?FALSE:TRUE);
}
#line 108 "inform7/Chapter 23/Rule Placement Sentences.w"
int does_nothing_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 74 "inform7/Chapter 23/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C23NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 110 "inform7/Chapter 23/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 111 "inform7/Chapter 23/Rule Placement Sentences.w"
#line 115 "inform7/Chapter 23/Rule Placement Sentences.w"
void Code__Rules__constrain_effect(parse_node *p1, parse_node *p2, int sense) {
if (Parser__Nodes__type(p1) == AND_NT) {
Code__Rules__constrain_effect(p1->down, p2, sense);
Code__Rules__constrain_effect(p1->down->next, p2, sense);
return;
}
parse_nt_against_word_range(does_nothing_sentence_subject_NTM, p1->word_ref1, p1->word_ref2, NULL, NULL);
if (most_recent_result == FALSE) return;
rule *existing_rule = most_recent_result_p;
if (p2)
Code__Rules__impose_constraint(NULL, existing_rule, p2->word_ref1, p2->word_ref2, sense);
else
Code__Rules__impose_constraint(NULL, existing_rule, -1, -1, FALSE);
}
#line 133 "inform7/Chapter 23/Rule Placement Sentences.w"
rule *relative_to_which = NULL;
#line 143 "inform7/Chapter 23/Rule Placement Sentences.w"
int listed_in_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 74 "inform7/Chapter 23/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C23NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 145 "inform7/Chapter 23/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 146 "inform7/Chapter 23/Rule Placement Sentences.w"
#line 150 "inform7/Chapter 23/Rule Placement Sentences.w"
int listed_in_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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: *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 6: *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 7:
{
#line 177 "inform7/Chapter 23/Rule Placement Sentences.w"
*X = BAD_RULE_PLACEMENT;
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C23UnspecifiedRulebookPlacement));
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 158 "inform7/Chapter 23/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8:
{
#line 177 "inform7/Chapter 23/Rule Placement Sentences.w"
*X = BAD_RULE_PLACEMENT;
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C23UnspecifiedRulebookPlacement));
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 159 "inform7/Chapter 23/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9:
{
#line 177 "inform7/Chapter 23/Rule Placement Sentences.w"
*X = BAD_RULE_PLACEMENT;
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C23UnspecifiedRulebookPlacement));
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 160 "inform7/Chapter 23/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10:
{
#line 189 "inform7/Chapter 23/Rule Placement Sentences.w"
*X = BAD_RULE_PLACEMENT;
{
#line 195 "inform7/Chapter 23/Rule Placement Sentences.w"
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C23ImproperRulePlacement));
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 23/Rule Placement Sentences.w"
;
}
#line 161 "inform7/Chapter 23/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 162 "inform7/Chapter 23/Rule Placement Sentences.w"
int offset_rule_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 74 "inform7/Chapter 23/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C23NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 165 "inform7/Chapter 23/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 23/Rule Placement Sentences.w"
int destination_rulebook_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 23/Rule Placement Sentences.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C23NoSuchRulebookPlacement));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rulebook was required.");
Problems__issue_problem_end();
}
#line 169 "inform7/Chapter 23/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 23/Rule Placement Sentences.w"
#line 217 "inform7/Chapter 23/Rule Placement Sentences.w"
void Code__Rules__manual_placement(int verb, parse_node *subj) {
switch(verb) {
case IN_RULEBOOK_VB:
Code__Rules__place_in_rulebook(subj, subj->next, TRUE);
break;
case NOT_IN_RULEBOOK_VB:
Code__Rules__place_in_rulebook(subj, subj->next, FALSE);
break;
case NO_EFFECT_IF_VB:
Code__Rules__constrain_effect(subj, subj->next, FALSE);
break;
case NO_EFFECT_UNLESS_VB:
Code__Rules__constrain_effect(subj, subj->next, TRUE);
break;
case NO_EFFECT_AT_ALL_VB:
Code__Rules__constrain_effect(subj, NULL, NOT_APPLICABLE);
break;
case SUBSTITUTES_VB:
Code__Rules__request_substitute(subj, subj->next, NULL, NOT_APPLICABLE);
break;
case SUBSTITUTES_IF_VB:
Code__Rules__request_substitute(subj, subj->next, subj->next->next, TRUE);
break;
case SUBSTITUTES_UNLESS_VB:
Code__Rules__request_substitute(subj, subj->next, subj->next->next, FALSE);
break;
}
}
#line 249 "inform7/Chapter 23/Rule Placement Sentences.w"
void Code__Rules__place_in_rulebook(parse_node *p1, parse_node *p2, int sense) {
if (Parser__Nodes__type(p1) == AND_NT) {
Code__Rules__place_in_rulebook(p1->down, p2, sense);
Code__Rules__place_in_rulebook(p1->down->next, p2, sense);
return;
}
int side, new_rule_placement, pw1, pw2;
LOGIF(RULE_ATTACHMENTS, "Placement sentence (%d):\np1=$T\np2=$T\n", sense, p1, p2);
pw1 = p2->word_ref1; pw2 = p2->word_ref2;
relative_to_which = NULL;
int pc = problem_count;
parse_nt_against_word_range(listed_in_sentence_object_NTM, pw1, pw2, 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 23/Rule Placement Sentences.w"
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C23ImproperRulePlacement));
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 270 "inform7/Chapter 23/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__handmade_problem(_P_(C23BadRulePlacementNegation));
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;
}
parse_nt_against_word_range(listed_in_sentence_subject_NTM, p1->word_ref1, p1->word_ref2, 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) Code__Rulebooks__detach_rule(rb, existing_rule);
return;
}
if (sense == FALSE) {
Code__Rulebooks__affected_by_placement(the_rulebook, current_sentence);
Code__Rulebooks__detach_rule(the_rulebook, existing_rule);
return;
}
booking *new_rule_booking = Code__Rules__Bookings__new(existing_rule);
Code__Rules__set_kind_from(existing_rule, the_rulebook);
if (relative_to_which) {
int rel1 = relative_to_which->word_ref1, rel2 = relative_to_which->word_ref2;
LOGIF(RULE_ATTACHMENTS, "Relative to which = $W\n", rel1, rel2);
Code__Rulebooks__affected_by_placement(the_rulebook, current_sentence);
if (Code__Rulebooks__rule_in_rulebook(relative_to_which, the_rulebook) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, the_rulebook->word_ref1, the_rulebook->word_ref2);
Problems__quote_words(3, rel1, rel2);
Problems__handmade_problem(_P_(C23PlaceWithMissingRule));
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;
}
}
Code__Rulebooks__attach_rule(the_rulebook, new_rule_booking, new_rule_placement,
side, relative_to_which);
}
#line 55 "inform7/Chapter 23/Stacked Variables.w"
void stv_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 Code__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 Code__StackedVariables__get_owner_id(stacked_variable *stv) {
return stv->owner_id;
}
int Code__StackedVariables__get_offset(stacked_variable *stv) {
return stv->offset_in_owning_frame;
}
kind *Code__StackedVariables__get_kind(stacked_variable *stv) {
nonlocal_variable *nlv = Code__StackedVariables__get_variable(stv);
return Data__NonlocalVariables__kind(nlv);
}
nonlocal_variable *Code__StackedVariables__get_variable(stacked_variable *stv) {
if (stv == NULL) return NULL;
return stv->underlying_var;
}
void Code__StackedVariables__set_matching_text(stacked_variable *stv, int w1, int w2) {
stv->mw1 = w1; stv->mw2 = w2;
}
void stv_get_matching_text(stacked_variable *stv, int *w1, int *w2) {
*w1 = stv->mw1; *w2 = stv->mw2;
}
stacked_variable *Code__StackedVariables__Owners__parse_match_clause(stacked_variable_owner *stvo,
int w1, int w2) {
stacked_variable_list *stvl;
for (stvl = stvo->list_of_stvs; stvl; stvl = stvl->next) {
int kw1 = stvl->the_stv->mw1, kw2 = stvl->the_stv->mw2;
if (w2-w1 < kw2-kw1) continue;
if (Text__compare_word_range(kw1, kw2, w1, w1+kw2-kw1))
return stvl->the_stv;
}
return NULL;
}
stacked_variable_owner *Code__StackedVariables__Owners__new(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 Code__StackedVariables__Owners__empty(stacked_variable_owner *stvo) {
if (stvo->no_stvs == 0) return TRUE;
return FALSE;
}
stacked_variable *Code__StackedVariables__Owners__add(stacked_variable_owner *stvo,
int w1, int w2, kind *K) {
stacked_variable *stv = CREATE(stacked_variable);
nonlocal_variable *q;
Text__Languages__remove_the(&w1, &w2);
stv->word_ref1 = w1;
stv->word_ref2 = w2;
stv->owner_id = stvo->recognition_id;
stv->offset_in_owning_frame = stvo->no_stvs++;
stv->assigned_at = current_sentence;
stv->mw1 = -1; stv->mw2 = -1;
stvo->list_of_stvs = stvl_add_to_list(stvo->list_of_stvs, stv);
if (stvo->no_stvs > max_frame_size_needed)
max_frame_size_needed = stvo->no_stvs;
q = Data__NonlocalVariables__new_stacked(w1, w2, K, stv);
stv->underlying_var = q;
char lv[32], rv[32];
Code__StackedVariables__compile_rvalue_to_text(stv, rv);
stv_compile_lvalue_to_text(stv, lv);
Data__NonlocalVariables__set_I6_identifier(q, rv, lv);
return stv;
}
stacked_variable_owner_list *Code__StackedVariables__Owners__Lists__add_owner(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 *Code__StackedVariables__Owners__Lists__append(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 = Code__StackedVariables__Owners__Lists__add_owner(new_head, extras->stvo);
return new_head;
}
int stvl_length(stacked_variable_list *stvl) {
int l = 0;
while (stvl) {
l++;
stvl = stvl->next;
}
return l;
}
void Code__StackedVariables__Owners__index(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)) {
Formats__HTML__open_para(ifl, 2, "tight");
Data__NonlocalVariables__index_single(stvl->the_stv->underlying_var);
INDEX("</p>");
}
}
stacked_variable *Code__StackedVariables__Owners__Lists__parse(stacked_variable_owner_list *stvol, int w1, int w2) {
if ((w1<0) || (w2<w1)) return NULL;
Text__Languages__remove_the(&w1, &w2);
while (stvol) {
stacked_variable *stv = NULL;
if (stvol->stvo) stv = stvl_parse(stvol->stvo->list_of_stvs, w1, w2);
if (stv) return stv;
stvol = stvol->next;
}
return NULL;
}
stacked_variable *stvl_parse(stacked_variable_list *stvl, int w1, int w2) {
while (stvl) {
if (Text__compare_word_range(stvl->the_stv->word_ref1, stvl->the_stv->word_ref2, w1, w2))
return stvl->the_stv;
stvl = stvl->next;
}
return NULL;
}
stacked_variable_list *stvl_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 Code__StackedVariables__Owners__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 = Code__Routines__begin_numbered(OUT, name_prototype, name_id);
Code__LocalVariables__add_named_call("pos");
Code__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 = Code__StackedVariables__get_variable(stvl->the_stv);
kind *K = Data__NonlocalVariables__kind(q);
WRITE("MStack-->pos = ");
if (Kinds__uses_pointer_values(K))
Kinds__RunTime__compile_heap_allocation(OUT, K, 1, -1);
else
Data__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 = Code__StackedVariables__get_variable(stvl->the_stv);
kind *K = Data__NonlocalVariables__kind(q);
if (Kinds__uses_pointer_values(K)) WRITE("BlkValueFree(MStack-->pos);\n");
WRITE("pos++;\n");
}
OUTDENT; WRITE("}\n");
WRITE("return %d;\n", i);
OUT = Code__Routines__end(OUT);
return i;
}
#line 68 "inform7/Chapter 24/Chronology.w"
time_period Code__Chronology__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 Code__Chronology__TimePeriods__new_tense_marker(int t) {
time_period tp = Code__Chronology__TimePeriods__new();
tp.tense = t;
return tp;
}
time_period *Code__Chronology__TimePeriods__store(time_period tp) {
time_period *ntp = CREATE(time_period);
*ntp = tp;
return ntp;
}
void Code__Chronology__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 Code__Chronology__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(": "); Code__Chronology__log_tense_number(tp->tense);
}
LOG(">");
}
int Code__Chronology__TimePeriods__is_valid(time_period *tp) {
return tp->valid_tp;
}
void Code__Chronology__TimePeriods__make_invalid(time_period *tp) {
tp->valid_tp = FALSE;
}
int Code__Chronology__TimePeriods__get_tense(time_period *tp) {
return tp->tense;
}
void Code__Chronology__TimePeriods__set_tense(time_period *tp, int t) {
tp->tense = t;
}
int tp_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 Code__Chronology__TimePeriods__compare_specificity(time_period *tp1, time_period *tp2) {
int dc1, dc2;
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;
dc1 = tp_duration_count(tp1); dc2 = tp_duration_count(tp2);
if (dc1 > dc2) return -1;
if (dc1 < dc2) return 1;
return 0;
}
#line 187 "inform7/Chapter 24/Chronology.w"
int historical_reference_possible_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 189 "inform7/Chapter 24/Chronology.w"
#line 193 "inform7/Chapter 24/Chronology.w"
int historical_reference_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 196 "inform7/Chapter 24/Chronology.w"
int repetition_specification_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 206 "inform7/Chapter 24/Chronology.w"
int repetitions_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 210 "inform7/Chapter 24/Chronology.w"
int iteration_repetitions_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 217 "inform7/Chapter 24/Chronology.w"
int turn_repetitions_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 221 "inform7/Chapter 24/Chronology.w"
int rep_number_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 226 "inform7/Chapter 24/Chronology.w"
#line 230 "inform7/Chapter 24/Chronology.w"
time_period Code__Chronology__TimePeriods__parse(int w1, int w2) {
time_period tp = Code__Chronology__TimePeriods__new();
if (parse_nt_against_word_range(historical_reference_possible_NTM, w1, w2, NULL, NULL)) {
int k;
for (k = w1; k <= w2; k++) {
to_NTMV = -1;
if (parse_nt_against_word_range(historical_reference_NTM, k, w2, 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", k, w2, &tp);
break;
}
}
}
return tp;
}
#line 261 "inform7/Chapter 24/Chronology.w"
int no_past_tenses = 0, no_past_actions = 0;
int too_late_for_past_tenses = FALSE;
void ap_compile_forced_to_present(OUTPUT_STREAM, action_pattern ap) {
Plugins__Actions__Patterns__convert_to_present_tense(&ap); /* prevent recursion */
TEMPORARY_STREAM;
Plugins__Actions__Patterns__compile_pattern_match(TEMP, ap, FALSE);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
void Code__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,
"Code__Chronology__compile_past_action_pattern on: $A\nat: $t\n", &ap, &duration);
if (Plugins__Actions__Patterns__makes_callings(&ap)) {
Problems__sentence_problem(_P_(C24PTAPMakesCallings),
"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 Code__Chronology__compile_past_tense_condition(OUTPUT_STREAM, time_period duration,
specification *spec) {
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;
LOGIF(TIME_PERIODS,
"Code__Chronology__compile_past_tense_condition on: $S\nat: $t\nNPT: %d\n",
spec, &duration, no_past_tenses);
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 = ">=";
if ((Specifications__species_is(spec, TEST_PROPOSITION_SPC)) && (Specifications__get_proposition(spec))) {
pcalc_prop *unnegated_prop = Calculus__Propositions__unnegate(Specifications__get_proposition(spec));
if (unnegated_prop) {
if (Specifications__test_flag(spec, CONDITION_NEGATED_SPFLAG))
Specifications__clear_flag(spec, CONDITION_NEGATED_SPFLAG);
else
Specifications__set_flag(spec, CONDITION_NEGATED_SPFLAG);
Specifications__set_proposition(spec, unnegated_prop);
}
if (Calculus__Deferrals__detect_locals(Specifications__get_proposition(spec), NULL) > 0) {
Problems__sentence_problem(_P_(BelievedImpossible), /* the S-parser catches these earlier now */
"conditions written in the past tense or referring to the past "
"with clauses like 'for the second time' cannot refer to "
"temporary values",
"because these have no past. For instance, the name given in a "
"'repeat...' or a 'let' can't be talked about as having "
"existed before.");
return;
}
}
if ((Specifications__species_is(spec, TEST_PAST_ACTION_SPC)) &&
(duration.units == TIMES_UNIT) &&
(duration.length >= 2)) {
Problems__sentence_problem(_P_(C24NoMoreRonNewcombMoment),
"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 (Specifications__test_flag(spec, CONDITION_NEGATED_SPFLAG)) WRITE("(~~");
int output_wanted = 1 + turns_flag;
WRITE("(TestSinglePastState(%d, %d, false, %d)",
past_flag, no_past_tenses, output_wanted + 4*perfect_flag);
if (Code__Chronology__TimePeriods__is_valid(&duration))
if ((duration.inform6_operator != NULL) || (duration.length >= 0))
WRITE(" %s %d ", op, duration.length);
WRITE(")");
if (Specifications__test_flag(spec, CONDITION_NEGATED_SPFLAG)) WRITE(")");
if (no_past_tenses >= 1024) { /* limit imposed by the Z-machine implementation */
Problems__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;
ptc->condition = Specifications__copy(spec);
Specifications__clear_flag(ptc->condition, CONDITION_NEGATED_SPFLAG);
Specifications__set_condition_tense(ptc->condition, NULL);
no_past_tenses++;
}
#line 405 "inform7/Chapter 24/Chronology.w"
void Code__Chronology__allow_no_further_past_tenses(void) {
too_late_for_past_tenses = TRUE;
}
#line 435 "inform7/Chapter 24/Chronology.w"
void Code__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 = Code__Routines__begin(OUT, i6_routine_identifier);
WRITE("if (");
ap_compile_forced_to_present(OUT, pta->historic_action);
WRITE(") rtrue;\n");
WRITE("rfalse;\n");
if ((Code__LocalVariables__are_we_using_table_lookup()) && (once_only)) {
once_only = FALSE;
Problems__sentence_problem(_P_(C24PastTableLookup),
"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 = Code__Routines__end(OUT);
}
WRITE("Array PastActionsI6Routines --> ");
LOOP_OVER(pta, past_tense_action_record) {
WRITE("PAPR_%d ", pta->allocation_id);
}
WRITE("0 0;\n");
}
#line 478 "inform7/Chapter 24/Chronology.w"
void Code__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 = Code__Routines__begin(OUT, "TestSinglePastState");
Code__LocalVariables__add_named_call("past_flag");
Code__LocalVariables__add_named_call("pt");
Code__LocalVariables__add_named_call("turn_end");
Code__LocalVariables__add_named_call("wanted");
Code__LocalVariables__add_internal_local("old");
Code__LocalVariables__add_internal_local("new");
Code__LocalVariables__add_internal_local("trips");
Code__LocalVariables__add_internal_local("consecutives");
Code__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) {
specification *spec = ptc->condition;
LOGIF(TIME_PERIODS, "Number %d: proposition $D\n",
ptc->allocation_id, Specifications__get_proposition(spec));
WRITE("%d: ", ptc->allocation_id);
current_sentence = ptc->where_ptc_tested; /* ensure problems reported correctly */
if (Calculus__Propositions__contains_callings(Specifications__get_proposition(spec))) {
Problems__sentence_problem(_P_(C24PastCallings),
"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.");
continue;
}
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
{
#line 569 "inform7/Chapter 24/Chronology.w"
TEMPORARY_STREAM;
WRITE("new = ");
Specifications__compile(TEMP, spec);
STREAM_COPY(OUT, TEMP);
WRITE(";\n");
CLOSE_TEMPORARY_STREAM;
}
#line 522 "inform7/Chapter 24/Chronology.w"
;
END_COMPILATION_MODE;
if ((Code__LocalVariables__are_we_using_table_lookup()) && (once_only)) {
once_only = FALSE;
Problems__sentence_problem(_P_(C24PastTableEntries),
"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 = Code__Routines__end(OUT);
LOGIF(TIME_PERIODS,
"Creation of past tense conditions complete\n");
}
#line 585 "inform7/Chapter 24/Chronology.w"
void Code__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 107 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, actions_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_COMPILE_CONSTANT, actions_compile_constant);
PLUGIN_REGISTER(PLUGIN_OFFERED_PROPERTY, actions_offered_property);
PLUGIN_REGISTER(PLUGIN_OFFERED_SPECIFICATION, actions_offered_specification);
PLUGIN_REGISTER(PLUGIN_TYPECHECK_EQUALITY, actions_typecheck_equality);
PLUGIN_REGISTER(PLUGIN_FORBID_SETTING, actions_forbid_setting);
}
#line 119 "inform7/Chapter 24/Actions.w"
int actions_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) {
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 135 "inform7/Chapter 24/Actions.w"
int actions_compile_constant(OUTPUT_STREAM, kind *K, specification *spec) {
if (Config__Plugins__plugged_in(actions_plugin) == FALSE)
internal_error("actions plugin inactive");
if (Kinds__eq(K, K_action_name)) {
action_name *an = action_name_spec_to_action_name(spec);
WRITE("##%s", Plugins__Actions__identifier(an));
return TRUE;
}
if (Kinds__eq(K, K_description_of_action)) {
action_pattern *ap = RETRIEVE_FROM_SPEC(spec, action_pattern);
Plugins__Actions__Patterns__compile_pattern_match(OUT, *ap, FALSE);
return TRUE;
}
if (Kinds__eq(K, K_stored_action)) {
action_pattern *ap = RETRIEVE_FROM_SPEC(spec, action_pattern);
Plugins__Actions__Patterns__as_stored_action(OUT, ap);
return TRUE;
}
return FALSE;
}
int actions_offered_property(kind *K, specification *owner, parse_node *what) {
if (Kinds__eq(K, K_action_name)) {
action_name *an = action_name_spec_to_action_name(owner);
if (an == NULL) internal_error("failed to extract action-name structure");
if (traverse == 1) an_add_variable(an, what);
return TRUE;
}
return FALSE;
}
int actions_offered_specification(specification *owner, int w1, int w2) {
if (Specifications__Values__is_CONSTANT_of_kind(owner, K_action_name)) {
actions_set_specification_text(action_name_spec_to_action_name(owner), w1);
return TRUE;
}
return FALSE;
}
#line 179 "inform7/Chapter 24/Actions.w"
int actions_typecheck_equality(kind *K1, kind *K2) {
if ((Kinds__eq(K1, K_stored_action)) &&
(Kinds__eq(K2, K_description_of_action)))
return TRUE;
return FALSE;
}
#line 193 "inform7/Chapter 24/Actions.w"
int actions_forbid_setting(kind *K) {
if (Kinds__eq(K, K_description_of_action)) {
Problems__sentence_problem(_P_(C24SetStoredAction),
"that would use 'now' to set a value to an action",
"and you've written this action as a condition: you need to use the "
"form 'action of...' instead. For instance, 'now X is the action of "
"taking the diamonds' is legal, but 'now X is taking the diamonds' "
"is not.");
return TRUE;
}
return FALSE;
}
#line 209 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__coerce_TEST_ACTION_to_STORED_ACTION(specification *spec) {
if (Specifications__species_is(spec, TEST_ACTION_SPC) == FALSE)
internal_error("can't coerce non-TEST_ACTION_SPC");
Specifications__coerce_to(spec, VALUE_FMY, CONSTANT_SPC);
Specifications__set_kind_of_value(spec, K_stored_action);
}
#line 227 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__coerce_TEST_ACTION_to_DESCRIPTION_OF_ACTION(specification *spec) {
if (Specifications__species_is(spec, TEST_ACTION_SPC) == FALSE)
internal_error("can't coerce non-TEST_ACTION_SPC");
Specifications__coerce_to(spec, VALUE_FMY, CONSTANT_SPC);
Specifications__set_kind_of_value(spec, K_description_of_action);
}
#line 245 "inform7/Chapter 24/Actions.w"
int notable_actions_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 247 "inform7/Chapter 24/Actions.w"
#line 252 "inform7/Chapter 24/Actions.w"
int action_name_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 254 "inform7/Chapter 24/Actions.w"
#line 258 "inform7/Chapter 24/Actions.w"
action_name *act_new(int w1, int w2, int implemented_by_I7) {
action_name *an;
an = CREATE(action_name);
if ((parse_nt_against_word_range(notable_actions_NTM, w1, w2, NULL, NULL)) && (going_action == NULL)) going_action = an;
an->word_ref1 = w1; an->word_ref2 = w2;
int plw1, plw2;
Text__make_past_of_participle(w1, w2, &plw1, &plw2);
an->past_word_ref1 = plw1; an->past_word_ref2 = plw2;
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_assemblage(
MISCELLANEOUS_MC, ACTION_NAME_SMC,
Text__Languages__merge(action_name_construction_NTM, 0,
Text__Words__from_range(w1, w2)),
STORE_POINTER_action_name(an));
Kinds__new_enumerated_value(K_action_name);
LOGIF(ACTION_CREATIONS, "Created action: $W\n", w1, w2);
if (implemented_by_I7) {
int wn;
an->use_verb_routine_in_I6_library = FALSE;
wn = lexer_wordcount;
Text__feed_into_lexer("check", TRUE, NULL);
Text__splice_words(an->word_ref1, an->word_ref2);
an->check_rules =
Code__Rulebooks__new_automatic(wn, lexer_wordcount-1, K_action_name,
NO_OUTCOME, TRUE, FALSE, FALSE);
Code__Rulebooks__fragment_by_actions(an->check_rules, 1);
wn = lexer_wordcount;
Text__feed_into_lexer("carry out", TRUE, NULL);
Text__splice_words(an->word_ref1, an->word_ref2);
an->carry_out_rules =
Code__Rulebooks__new_automatic(wn, lexer_wordcount-1, K_action_name,
NO_OUTCOME, TRUE, FALSE, FALSE);
Code__Rulebooks__fragment_by_actions(an->carry_out_rules, 2);
wn = lexer_wordcount;
Text__feed_into_lexer("report", TRUE, NULL);
Text__splice_words(an->word_ref1, an->word_ref2);
an->report_rules =
Code__Rulebooks__new_automatic(wn, lexer_wordcount-1, K_action_name,
NO_OUTCOME, TRUE, FALSE, FALSE);
Code__Rulebooks__fragment_by_actions(an->report_rules, 1);
an->owned_by_an = Code__StackedVariables__Owners__new(20000+an->allocation_id);
} else {
an->owned_by_an = NULL;
}
action_name *an2;
LOOP_OVER(an2, action_name)
if (an != an2)
if (action_names_overlap(an, an2)) {
an->it_optional = FALSE;
an2->it_optional = FALSE;
}
return an;
}
/* pointing at, pointing it at */
#line 353 "inform7/Chapter 24/Actions.w"
int action_pronoun_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 355 "inform7/Chapter 24/Actions.w"
#line 359 "inform7/Chapter 24/Actions.w"
int action_names_overlap(action_name *an1, action_name *an2) {
int w1 = an1->word_ref1, w2 = an1->word_ref2, x1 = an2->word_ref1, x2 = an2->word_ref2;
int i, j;
for (i = w1, j = x1; (i <= w2) && (j <= x2); i++, j++) {
if ((parse_nt_against_word_range(action_pronoun_NTM, i, i, NULL, NULL)) && (compare_words(i+1, j))) return TRUE;
if ((parse_nt_against_word_range(action_pronoun_NTM, j, j, NULL, NULL)) && (compare_words(j+1, i))) return TRUE;
if (compare_words(i, j) == FALSE) return FALSE;
}
return FALSE;
}
void Plugins__Actions__log(action_name *an) {
if (an == NULL) LOG("<null-action-name>");
else LOG("$W", an->word_ref1, an->word_ref2);
}
#line 380 "inform7/Chapter 24/Actions.w"
int action_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 381 "inform7/Chapter 24/Actions.w"
action_name *an;
LOOP_OVER(an, action_name)
if (Text__compare_word_range(w1, w2, an->word_ref1, an->word_ref2)) {
*XP = an;
return TRUE;
}
LOOP_OVER(an, action_name)
if (parse_nt_against_word_range(action_optional_trailing_prepositions_NTM, an->word_ref1, an->word_ref2, NULL, NULL)) {
int short1, short2;
GET_RW(action_optional_trailing_prepositions_NTM, 1, short1, short2);
if (Text__compare_word_range(w1, w2, short1, short2)) {
*XP = an;
return TRUE;
}
}
return FALSE;
}
#line 408 "inform7/Chapter 24/Actions.w"
int action_optional_trailing_prepositions_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 410 "inform7/Chapter 24/Actions.w"
#line 414 "inform7/Chapter 24/Actions.w"
action_name *Plugins__Actions__longest_null(int w1, int w2, int tense, int *excess) {
action_name *an;
LOOP_OVER(an, action_name)
if (an->max_parameters == 0) {
int aw1, aw2;
if (tense == IS_TENSE) { aw1 = an->word_ref1; aw2 = an->word_ref2; }
else { aw1 = an->past_word_ref1; aw2 = an->past_word_ref1; }
if ((w2 - w1 >= aw2 - aw1) &&
(Text__compare_word_range(w1, w1 + aw2 - aw1, aw1, aw2))) {
*excess = w1 + aw2 - aw1 + 1;
return an;
}
}
return NULL;
}
int Plugins__Actions__it_optional(action_name *an) {
return an->it_optional;
}
int Plugins__Actions__abbreviable(action_name *an) {
return an->abbreviable;
}
char *Plugins__Actions__identifier(action_name *an) {
return an->an_I6_identifier;
}
rulebook *Plugins__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 *Plugins__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 actions_set_specification_text(action_name *an, int wn) {
an->an_specification_text_word = wn;
}
int an_get_specification_text(action_name *an) {
return an->an_specification_text_word;
}
#line 472 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__name_all(void) {
action_name *an;
LOOP_OVER(an, action_name)
if (an->an_I6_identifier[0] == 0)
Formats__Inform6__compose_identifier(an->an_I6_identifier,
'A', an->allocation_id, an->word_ref1, an->word_ref2);
}
void Plugins__Actions__translates(int w1, int w2, parse_node *p2) {
action_name *an = NULL;
if (parse_nt_against_word_range(action_name_NTM, w1, w2, NULL, NULL)) an = most_recent_result_p;
else {
LOG("Tried action name $W\n", w1, w2);
Problems__sentence_problem(_P_(C24TranslatesNonAction),
"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", w1, w2, an->an_I6_identifier);
Problems__sentence_problem(_P_(C24TranslatesActionAlready),
"this action has already been translated",
"so there must be some duplication somewhere.");
return;
}
strcpy(an->an_I6_identifier, Text__word_text(p2->word_ref1));
LOGIF(ACTION_CREATIONS, "Translated action: $l as %s\n", an, Text__word_text(p2->word_ref1));
}
int Plugins__Actions__get_stem_length(action_name *an) {
int w1 = an->word_ref1, w2 = an->word_ref2, k = w1, s = 0;
if (w1<0) return 0; /* should never happen */
while (k<=w2) {
if (!(parse_nt_against_word_range(action_pronoun_NTM, k, k, NULL, NULL))) s++;
k++;
}
return s;
}
#line 520 "inform7/Chapter 24/Actions.w"
int action_variable_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 535 "inform7/Chapter 24/Actions.w"
*X = NOT_APPLICABLE;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C24BadMatchingSyntax));
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 522 "inform7/Chapter 24/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 524 "inform7/Chapter 24/Actions.w"
#line 528 "inform7/Chapter 24/Actions.w"
int action_variable_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 550 "inform7/Chapter 24/Actions.w"
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C24ActionVarAnd));
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 529 "inform7/Chapter 24/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 531 "inform7/Chapter 24/Actions.w"
#line 564 "inform7/Chapter 24/Actions.w"
void an_add_variable(action_name *an, parse_node *cnode) {
int nw1 = -1, nw2 = -1, tw1 = -1, tw2 = -1, mw1 = -1, mw2 = -1;
stacked_variable *stv = NULL;
if (Parser__Nodes__type(cnode) != PROPERTYCALLED_NT) {
Problems__quote_source(1, current_sentence);
Problems__handmade_problem(_P_(C24ActionVarUncalled));
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_words(2, nw1, nw2);
Problems__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;
}
tw1 = cnode->down->word_ref1; tw2 = cnode->down->word_ref2;
nw1 = cnode->down->next->word_ref1; nw2 = cnode->down->next->word_ref2;
if (parse_nt_against_word_range(action_variable_NTM, nw1, nw2, NULL, NULL)) {
if (most_recent_result == NOT_APPLICABLE) return;
GET_RW(action_variable_name_NTM, 1, nw1, nw2);
if (most_recent_result) {
GET_RW(action_variable_NTM, 1, mw1, mw2);
int x1, x2;
Text__dequote_word(mw1);
x1 = lexer_wordcount;
Text__feed_into_lexer(Text__word_text(mw1), FALSE, NULL);
x2 = lexer_wordcount-1;
mw1 = x1; mw2 = x2;
if (mw2 > mw1) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, mw1, mw2);
Problems__handmade_problem(_P_(C24MatchedAsTooLong));
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 (parse_nt_against_word_range(k_kind_NTM, tw1, tw2, NULL, NULL)) K = most_recent_result_p;
else {
specification *spec = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, tw1, tw2, NULL, NULL)) spec = most_recent_result_p;
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, tw1, tw2);
Problems__handmade_problem(_P_(C24ActionVarOverspecific));
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: $X", spec);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, tw1, tw2);
Problems__handmade_problem(_P_(C24ActionVarUnknownKOV));
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__eq(K, K_value)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, tw1, tw2);
Problems__handmade_problem(_P_(C24ActionVarValue));
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 (Code__StackedVariables__Owners__empty(an->owned_by_an)) {
all_nonempty_stacked_action_vars =
Code__StackedVariables__Owners__Lists__add_owner(all_nonempty_stacked_action_vars, an->owned_by_an);
}
stv = Code__StackedVariables__Owners__add(an->owned_by_an, nw1, nw2, K);
LOGIF(ACTION_CREATIONS, "Created action variable for $l: $W ($u)\n",
an, nw1, nw2, K);
if (mw1 >= 0) {
Code__StackedVariables__set_matching_text(stv, mw1, mw2);
LOGIF(ACTION_CREATIONS, "Match with text: $W + SP\n", mw1, mw2);
}
}
stacked_variable *Plugins__Actions__parse_match_clause(action_name *an, int w1, int w2) {
return Code__StackedVariables__Owners__parse_match_clause(an->owned_by_an, w1, w2);
}
void compile_action_name_var_creators(OUTPUT_STREAM) {
action_name *an;
LOOP_OVER(an, action_name) {
if ((an->owned_by_an) &&
(Code__StackedVariables__Owners__empty(an->owned_by_an) == FALSE))
Code__StackedVariables__Owners__compile_frame_creator(OUT, an->owned_by_an,
"ANSTVC_%d", an->allocation_id);
}
}
#line 706 "inform7/Chapter 24/Actions.w"
sentence_handler NEW_ACTION_SH_handler =
{ SENTENCE_NT, NEW_ACTION_VB, 1, act_parse_definition };
#line 718 "inform7/Chapter 24/Actions.w"
action_name *an_being_parsed = NULL;
#line 730 "inform7/Chapter 24/Actions.w"
int action_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 737 "inform7/Chapter 24/Actions.w"
*XP = NULL;
Problems__sentence_problem(_P_(C24ActionAlreadyExists),
"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 731 "inform7/Chapter 24/Actions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = act_new(w1, w2, TRUE);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 733 "inform7/Chapter 24/Actions.w"
#line 758 "inform7/Chapter 24/Actions.w"
int action_clause_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 764 "inform7/Chapter 24/Actions.w"
int action_applications_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 = 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 7: *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 8:
{
#line 858 "inform7/Chapter 24/Actions.w"
*X = REQUIRES_ACCESS; *XP = K_thing;
Problems__sentence_problem(_P_(C24ActionMisapplied),
"an action can only apply to things or to kinds of value",
"for instance: 'photographing is an action applying to "
"one visible thing'.");
}
#line 774 "inform7/Chapter 24/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 775 "inform7/Chapter 24/Actions.w"
int act_req_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = R[1]; *XP = RP[2];
{
#line 846 "inform7/Chapter 24/Actions.w"
if (Kinds__eq(*XP, K_thing)) {
if (*X == UNRESTRICTED_ACCESS) *X = REQUIRES_ACCESS;
*XP = K_object;
} else if (Kinds__lt(*XP, K_object)) {
{
#line 858 "inform7/Chapter 24/Actions.w"
*X = REQUIRES_ACCESS; *XP = K_thing;
Problems__sentence_problem(_P_(C24ActionMisapplied),
"an action can only apply to things or to kinds of value",
"for instance: 'photographing is an action applying to "
"one visible thing'.");
}
#line 850 "inform7/Chapter 24/Actions.w"
;
} else {
if (*X != UNRESTRICTED_ACCESS)
{
#line 858 "inform7/Chapter 24/Actions.w"
*X = REQUIRES_ACCESS; *XP = K_thing;
Problems__sentence_problem(_P_(C24ActionMisapplied),
"an action can only apply to things or to kinds of value",
"for instance: 'photographing is an action applying to "
"one visible thing'.");
}
#line 852 "inform7/Chapter 24/Actions.w"
;
}
}
#line 777 "inform7/Chapter 24/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 846 "inform7/Chapter 24/Actions.w"
if (Kinds__eq(*XP, K_thing)) {
if (*X == UNRESTRICTED_ACCESS) *X = REQUIRES_ACCESS;
*XP = K_object;
} else if (Kinds__lt(*XP, K_object)) {
{
#line 858 "inform7/Chapter 24/Actions.w"
*X = REQUIRES_ACCESS; *XP = K_thing;
Problems__sentence_problem(_P_(C24ActionMisapplied),
"an action can only apply to things or to kinds of value",
"for instance: 'photographing is an action applying to "
"one visible thing'.");
}
#line 850 "inform7/Chapter 24/Actions.w"
;
} else {
if (*X != UNRESTRICTED_ACCESS)
{
#line 858 "inform7/Chapter 24/Actions.w"
*X = REQUIRES_ACCESS; *XP = K_thing;
Problems__sentence_problem(_P_(C24ActionMisapplied),
"an action can only apply to things or to kinds of value",
"for instance: 'photographing is an action applying to "
"one visible thing'.");
}
#line 852 "inform7/Chapter 24/Actions.w"
;
}
}
#line 778 "inform7/Chapter 24/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 779 "inform7/Chapter 24/Actions.w"
int action_access_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 784 "inform7/Chapter 24/Actions.w"
#line 788 "inform7/Chapter 24/Actions.w"
int action_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 806 "inform7/Chapter 24/Actions.w"
Problems__sentence_problem(_P_(C24ActionClauseUnknown),
"the action definition contained text I couldn't follow",
"and may be too complicated.");
}
#line 790 "inform7/Chapter 24/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 791 "inform7/Chapter 24/Actions.w"
int action_clauses_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 813 "inform7/Chapter 24/Actions.w"
int c1, c2;
switch (*X) {
case OOW_ACT_CLAUSE:
an_being_parsed->out_of_world = TRUE; break;
case PP_ACT_CLAUSE:
GET_RW(action_clause_NTM, 1, c1, c2);
if (c1 != c2) {
Problems__sentence_problem(_P_(C24MultiwordPastParticiple),
"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.)");
}
Text__set_past_participle(&(an_being_parsed->past_word_ref1), &(an_being_parsed->past_word_ref2), c2);
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;
break;
case LIGHT_ACT_CLAUSE:
an_being_parsed->requires_light = TRUE;
break;
case ABBREV_ACT_CLAUSE:
an_being_parsed->abbreviable = TRUE;
break;
}
}
#line 794 "inform7/Chapter 24/Actions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1];
{
#line 813 "inform7/Chapter 24/Actions.w"
int c1, c2;
switch (*X) {
case OOW_ACT_CLAUSE:
an_being_parsed->out_of_world = TRUE; break;
case PP_ACT_CLAUSE:
GET_RW(action_clause_NTM, 1, c1, c2);
if (c1 != c2) {
Problems__sentence_problem(_P_(C24MultiwordPastParticiple),
"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.)");
}
Text__set_past_participle(&(an_being_parsed->past_word_ref1), &(an_being_parsed->past_word_ref2), c2);
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;
break;
case LIGHT_ACT_CLAUSE:
an_being_parsed->requires_light = TRUE;
break;
case ABBREV_ACT_CLAUSE:
an_being_parsed->abbreviable = TRUE;
break;
}
}
#line 795 "inform7/Chapter 24/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 796 "inform7/Chapter 24/Actions.w"
int action_clause_terminated_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 802 "inform7/Chapter 24/Actions.w"
#line 867 "inform7/Chapter 24/Actions.w"
void act_parse_definition(parse_node *p) {
int aw1 = p->down->next->word_ref1, aw2 = p->down->next->word_ref2;
parse_nt_against_word_range(action_sentence_subject_NTM, aw1, aw2, NULL, NULL);
action_name *an = most_recent_result_p;
if (an == NULL) return;
if (p->down->next->next) {
int x1 = p->down->next->next->word_ref1;
int x2 = p->down->next->next->word_ref2;
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;
parse_nt_against_word_range(action_sentence_object_NTM, x1, x2, NULL, NULL);
}
if (an->max_parameters >= 2) {
if ((Kinds__le(an->noun_kind, K_object) == FALSE) &&
(Kinds__le(an->second_kind, K_object) == FALSE)) {
Problems__sentence_problem(_P_(C24ActionBothValues),
"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 Plugins__Actions__is_out_of_world(action_name *an) {
if (an->out_of_world) return TRUE;
return FALSE;
}
kind *Plugins__Actions__get_data_type_of_noun(action_name *an) {
return an->noun_kind;
}
kind *Plugins__Actions__get_data_type_of_second_noun(action_name *an) {
return an->second_kind;
}
void Plugins__Actions__set_text_to_name_tensed(action_name *an, int *x1, int *x2, int tense) {
if (tense == HASBEEN_TENSE) {
*x1 = an->past_word_ref1;
*x2 = an->past_word_ref2;
} else {
*x1 = an->word_ref1;
*x2 = an->word_ref2;
}
}
int Plugins__Actions__can_have_parameters(action_name *an) {
if (an->max_parameters > 0) return TRUE;
return FALSE;
}
int Plugins__Actions__get_max_parameters(action_name *an) {
return an->max_parameters;
}
#line 942 "inform7/Chapter 24/Actions.w"
int Plugins__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__le(an->noun_kind, K_object) == FALSE))
return FALSE;
return TRUE;
}
void Plugins__Actions__compile_action_bitmap_property(OUTPUT_STREAM) {
int i;
for (i=0; i<=((NUMBER_CREATED(action_name))/16); i++) WRITE("0 ");
}
void Plugins__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 968 "inform7/Chapter 24/Actions.w"
void Plugins__Actions__add_gl(action_name *an, grammar_line *gl) {
if (an->list_with_action == NULL) an->list_with_action = gl;
else Plugins__Parsing__Lines__list_with_action_add(an->list_with_action, gl);
}
void Plugins__Actions__remove_gl(action_name *an) {
an->list_with_action = NULL;
}
#line 980 "inform7/Chapter 24/Actions.w"
void Plugins__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__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__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__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__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_words(2,
an->designers_specification->word_ref1,
an->designers_specification->word_ref2);
}
Problems__quote_words(3, an->word_ref1, an->word_ref2);
Problems__quote_text(4, failed_on);
Problems__handmade_problem(_P_(C24GrammarMismatchesAction));
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 1095 "inform7/Chapter 24/Actions.w"
void Plugins__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 = Code__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 = Code__Routines__end(OUT);
}
}
#line 1114 "inform7/Chapter 24/Actions.w"
void Plugins__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__RuntimeIDs__compile_strong(OUT, an->noun_kind); WRITE(" ");
Kinds__RuntimeIDs__compile_strong(OUT, an->second_kind); WRITE(" ");
if ((an->owned_by_an) &&
(Code__StackedVariables__Owners__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);
compile_action_name_var_creators(OUT);
Code__VirtualMachines__note_usage("action", -1, -1, NULL, 12, 0, TRUE);
OUT = Code__Routines__begin(OUT, "DB_Action_Details");
Code__LocalVariables__add_named_call("act");
Code__LocalVariables__add_named_call("n");
Code__LocalVariables__add_named_call("s");
Code__LocalVariables__add_named_call("for_say");
DB_Action_Details(OUT);
OUT = Code__Routines__end(OUT);
}
void 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 = an->word_ref1, j0 = -1, somethings = 0, clc = 0;
while (j <= an->word_ref2) {
if (parse_nt_against_word_range(action_pronoun_NTM, j, j, NULL, NULL)) {
if (j0 >= 0) {
{
#line 1199 "inform7/Chapter 24/Actions.w"
if (clc++ > 0) WRITE("print \" \"; ");
}
#line 1165 "inform7/Chapter 24/Actions.w"
;
WRITE("print \"");
print_action_text_to(j0, j-1, an->word_ref1, OUT);
WRITE("\"; ");
j0 = -1;
}
{
#line 1199 "inform7/Chapter 24/Actions.w"
if (clc++ > 0) WRITE("print \" \"; ");
}
#line 1171 "inform7/Chapter 24/Actions.w"
;
WRITE("if (for_say == 2) print \"it\"; else ");
cat_something2(OUT, an, somethings++);
} else {
if (j0<0) j0 = j;
}
j++;
}
if (j0 >= 0) {
{
#line 1199 "inform7/Chapter 24/Actions.w"
if (clc++ > 0) WRITE("print \" \"; ");
}
#line 1180 "inform7/Chapter 24/Actions.w"
;
WRITE("print \"");
print_action_text_to(j0, j-1, an->word_ref1, OUT);
WRITE("\"; ");
}
if (somethings < an->max_parameters) {
WRITE("if (for_say ~= 2) { ");
{
#line 1199 "inform7/Chapter 24/Actions.w"
if (clc++ > 0) WRITE("print \" \"; ");
}
#line 1187 "inform7/Chapter 24/Actions.w"
;
cat_something2(OUT, an, somethings++);
WRITE("}");
}
WRITE("\n");
}
OUTDENT; WRITE("}\n");
}
#line 1204 "inform7/Chapter 24/Actions.w"
void 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__le(K, K_object) == FALSE) var = "parsed_number";
WRITE("%s(%s); ", Kinds__get_name_of_printing_rule_ACTIONS(K), var);
}
void print_action_text_to(int w1, int w2, int start, OUTPUT_STREAM) {
if (w1 == start) {
Text__print_text_to_stream(w1, w1, OUT);
if (w1 == w2) return;
WRITE(" ");
w1++;
}
Text__print_raw_text_to_stream(w1, w2, OUT);
}
void Plugins__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 1240 "inform7/Chapter 24/Actions.w"
int Plugins__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 = Parser__Sentences__Headings__heading_of(Text__word_location(an->word_ref1));
*new_par = FALSE;
if (pass == 1) {
extension_file *this_extension =
Parser__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)) {
int x1, x2;
if (f) INDEX("<p>");
Parser__Sentences__Headings__get_text(definition_area, &x1, &x2);
if (x1 >= 0) {
Code__Phrases__index_definition_area(x1, x2, 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>");
Text__print_raw_text_to_stream(an->word_ref1, an->word_ref2, ifl);
if (bold) INDEX("</b>");
} else {
int j = an->word_ref1;
int somethings = 0;
while (j <= an->word_ref2) {
if (parse_nt_against_word_range(action_pronoun_NTM, j, j, NULL, NULL)) {
act_index_something(an, somethings++);
} else {
Text__print_raw_text_to_stream(j, j, ifl);
INDEX(" ");
}
j++;
}
if (somethings < an->max_parameters)
act_index_something(an, somethings++);
}
if (an->out_of_world) INDEX("</font>");
if (pass == 2) {
int swn = an_get_specification_text(an);
INDEX("</b>");
Index__link(an->designers_specification->word_ref1);
Index__anchor(an->an_I6_identifier);
if (an->requires_light) INDEX(" (requires light)");
INDEX(" (<i>past tense</i> ");
Text__print_raw_text_to_stream(an->past_word_ref1, an->past_word_ref2, ifl);
INDEX(")<br>\n");
INDEX("<p>");
if (swn >= 0) {
Text__print_text_to_stream(swn, swn, ifl);
INDEX("<p>");
}
INDEX("<hr>");
INDEX("<p><b>Typed commands leading to this action</b><p>\n");
if (Plugins__Parsing__Lines__index_list_with_action(an->list_with_action) == FALSE)
INDEX("<i>None</i>");
if (Code__StackedVariables__Owners__empty(an->owned_by_an) == FALSE) {
INDEX("<p><b>Named values belonging to this action</b></p>\n");
Code__StackedVariables__Owners__index(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) {
Code__Rulebooks__index_action_rules(an, NULL, PERSUASION_RB, "persuasion", &resp_count);
Code__Rulebooks__index_action_rules(an, NULL, UNSUCCESSFUL_ATTEMPT_BY_RB, "unsuccessful attempt", &resp_count);
Code__Rulebooks__index_action_rules(an, NULL, SETTING_ACTION_VARIABLES_RB, "set action variables for", &resp_count);
Code__Rulebooks__index_action_rules(an, NULL, BEFORE_RB, "before", &resp_count);
Code__Rulebooks__index_action_rules(an, NULL, INSTEAD_RB, "instead of", &resp_count);
}
Code__Rulebooks__index_action_rules(an, an->check_rules, CHECK_RB, "check", &resp_count);
Code__Rulebooks__index_action_rules(an, an->carry_out_rules, CARRY_OUT_RB, "carry out", &resp_count);
if (an->out_of_world == FALSE) {
Code__Rulebooks__index_action_rules(an, NULL, AFTER_RB, "after", &resp_count);
}
Code__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(an->designers_specification->word_ref1);
Index__detail_link("A", an->allocation_id, (on_details_page)?FALSE:TRUE);
}
return f;
}
void 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__le(K, K_object)) INDEX("something");
else if (Kinds__eq(K, K_understanding)) INDEX("some text");
else Kinds__Textual__write(ifl, K);
INDEX("</font> ");
}
#line 38 "inform7/Chapter 24/Action Name Lists.w"
action_name_list *anl_new(void) {
action_name_list *new_anl = CREATE(action_name_list);
new_anl->action_listed = NULL;
new_anl->parc = 0;
new_anl->word_position = -1;
new_anl->parity = 1;
new_anl->negate_pattern = FALSE;
new_anl->in_w1 = -1;
new_anl->in_w2 = -1;
new_anl->abbreviation_level = 0;
new_anl->anyone_specified = FALSE;
new_anl->delete_this_link = FALSE;
return new_anl;
}
void Plugins__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->word_ref1, anl->action_listed->word_ref2);
else LOG("NULL");
for (i=0; i<anl->parc; i++)
LOG(" [%d: $W]", i, anl->parameter_w1[i], anl->parameter_w2[i]);
LOG(" [in: $W]\n", anl->in_w1, anl->in_w2);
}
}
void Plugins__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->action_listed == NULL) LOG("ANY / ");
else {
if (a->parity == -1) LOG("not-");
LOG("$W / ", a->action_listed->word_ref1, a->action_listed->word_ref2);
}
}
if (anl->negate_pattern) LOG(" ]");
}
}
action_name *Plugins__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 105 "inform7/Chapter 24/Action Name Lists.w"
int action_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 120 "inform7/Chapter 24/Action Name Lists.w"
*X = TRUE;
action_name_list *new_anl = anl_new();
new_anl->word_position = w1;
*XP = new_anl;
}
#line 109 "inform7/Chapter 24/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 112 "inform7/Chapter 24/Action Name Lists.w"
int anl_excluded_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 206 "inform7/Chapter 24/Action Name Lists.w"
action_name_list *anl = flip_anl_parity(RP[1], TRUE);
if ((anl == NULL) ||
(Plugins__Actions__can_have_parameters(anl->action_listed) == FALSE))
return FALSE;
int x1, x2;
GET_RW(anl_excluded_NTM, 1, x1, x2);
anl->parameter_w1[anl->parc] = x1;
anl->parameter_w2[anl->parc] = x2;
anl->parc++;
*XP = anl;
}
#line 114 "inform7/Chapter 24/Action Name Lists.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = 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 116 "inform7/Chapter 24/Action Name Lists.w"
#line 137 "inform7/Chapter 24/Action Name Lists.w"
int anl_to_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 152 "inform7/Chapter 24/Action Name Lists.w"
action_name_list *anl = RP[1];
int x1, x2;
GET_RW(anl_in_tail_NTM, 1, x1, x2);
anl->in_w1 = x1;
anl->in_w2 = x2;
}
#line 138 "inform7/Chapter 24/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 140 "inform7/Chapter 24/Action Name Lists.w"
int anl_operand_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 161 "inform7/Chapter 24/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 = anl_new();
new_anl->word_position = w1;
}
new_anl->parameter_w1[new_anl->parc] = w1;
new_anl->parameter_w2[new_anl->parc] = w2;
new_anl->parc++;
*XP = new_anl;
}
#line 142 "inform7/Chapter 24/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 143 "inform7/Chapter 24/Action Name Lists.w"
int anl_in_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = FALSE; return FAIL_NONTERMINAL + anl_in_tail_NTM->range_result_w1[1] - w1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE; return FAIL_NONTERMINAL + anl_in_tail_NTM->range_result_w1[1] - w1;;
#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 148 "inform7/Chapter 24/Action Name Lists.w"
#line 176 "inform7/Chapter 24/Action Name Lists.w"
int anl_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 220 "inform7/Chapter 24/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 177 "inform7/Chapter 24/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 179 "inform7/Chapter 24/Action Name Lists.w"
int anl_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 24/Action Name Lists.w"
#line 195 "inform7/Chapter 24/Action Name Lists.w"
int anl_entry_NTMR(int w1, int w2, int *X, void **XP) {
#line 196 "inform7/Chapter 24/Action Name Lists.w"
action_name_list *anl = anl_parse_internal(w1, w2);
if (anl) {
*XP = anl; return TRUE;
}
return FALSE;
}
#line 235 "inform7/Chapter 24/Action Name Lists.w"
action_name_list *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 250 "inform7/Chapter 24/Action Name Lists.w"
int anl_parsing_tense = IS_TENSE;
action_name_list *Plugins__Actions__Lists__parse(int w1, int w2, int tense) {
int t = anl_parsing_tense;
anl_parsing_tense = tense;
int r = parse_nt_against_word_range(action_list_NTM, w1, w2, NULL, NULL);
anl_parsing_tense = t;
if (r) return most_recent_result_p;
return NULL;
}
#line 263 "inform7/Chapter 24/Action Name Lists.w"
action_name_list *anl_parse_internal(int w1, int w2) {
LOGIF(ACTION_PATTERN_PARSING, "Parsing ANL from $W (tense %d)\n", w1, w2, anl_parsing_tense);
int tense = anl_parsing_tense;
action_name_list *anl_list = NULL, *new_anl = NULL;
action_name *an;
int restorative_w2;
new_anl = anl_new();
anl_list = NULL;
restorative_w2 = w2;
LOOP_OVER(an, action_name) {
int w_m, x_m, x_ended = FALSE;
int x1, x2;
int fc = 0;
int it_optional = Plugins__Actions__it_optional(an);
int abbreviable = Plugins__Actions__abbreviable(an);
w2 = restorative_w2;
Plugins__Actions__set_text_to_name_tensed(an, &x1, &x2, tense);
new_anl->action_listed = an;
new_anl->parc = 0;
new_anl->word_position = w1;
new_anl->parity = 1;
new_anl->in_w1 = -1;
new_anl->in_w2 = -1;
w_m = w1; x_m = x1;
while ((w_m <= w2) && (x_m <= x2)) {
if (Text__word(x_m++) != Text__word(w_m++)) {
fc=1; goto DontInclude;
}
if (x_m > x2) { x_ended = TRUE; break; }
if (parse_nt_against_word_range(action_pronoun_NTM, x_m, x_m, NULL, NULL)) {
if (w_m > w2) x_ended = TRUE; else {
int j = -1, k;
for (k=(it_optional)?(w_m):(w_m+1); k<=w2; k++)
if (Text__word(k) == Text__word(x_m+1)) { j = k; break; }
if (j<0) { fc=2; goto DontInclude; }
if (j-1 >= w_m) {
new_anl->parameter_w1[new_anl->parc] = w_m;
new_anl->parameter_w2[new_anl->parc] = j-1;
new_anl->parc++;
} else {
new_anl->parameter_w1[new_anl->parc] = -1;
new_anl->parameter_w2[new_anl->parc] = -1;
new_anl->parc++;
}
w_m = j; x_m++;
}
}
if (x_ended) break;
}
if ((w_m > w2) && (x_ended == FALSE)) {
if (abbreviable) x_ended = TRUE;
else { fc=3; goto DontInclude; }
}
if (x_m <= x2) new_anl->abbreviation_level = x2-x_m+1;
int inc = FALSE;
if (w_m > w2) inc = TRUE;
else if (parse_nt_against_word_range(anl_in_tail_NTM, w_m, w2, NULL, NULL)) {
int x1, x2;
GET_RW(anl_in_tail_NTM, 1, x1, x2);
new_anl->in_w1 = x1;
new_anl->in_w2 = x2;
inc = TRUE;
} else if (Plugins__Actions__can_have_parameters(an)) {
anl_being_parsed = new_anl;
if (parse_nt_against_word_range(anl_to_tail_NTM, w_m, w2, 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 = anl_new();
DontInclude: ;
}
LOGIF(ACTION_PATTERN_PARSING, "Parsing ANL from $W resulted in:\n$L\n", w1, w2, anl_list);
return anl_list;
}
int scanning_anl_only_mode = FALSE;
action_name_list *Plugins__Actions__Lists__extract_actions_only(int w1, int w2) {
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 (parse_nt_against_word_range(action_pattern_NTM, w1, w2, NULL, NULL)) {
anl = Plugins__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 *Plugins__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 = Plugins__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 Plugins__Actions__Lists__get_explicit_anyone_flag(action_name_list *anl) {
if (anl == NULL) return FALSE;
return anl->anyone_specified;
}
int Plugins__Actions__Lists__negated(action_name_list *anl) {
if (anl == NULL) return FALSE;
return anl->negate_pattern;
}
void Plugins__Actions__Lists__compile(OUTPUT_STREAM, action_name_list *anl) {
if (anl == NULL) return;
LOGIF(ACTION_PATTERN_COMPILATION, "CANL: $L", anl);
WRITE("(action %s", (anl->parity==1)?"==":"~=");
while (anl != NULL) {
WRITE("##%s", Plugins__Actions__identifier(anl->action_listed));
if (anl->next != NULL) WRITE(" or ");
anl = anl->next;
}
WRITE(")");
}
#line 432 "inform7/Chapter 24/Action Name Lists.w"
int Plugins__Actions__Lists__compare_specificity(action_name_list *anl1, action_name_list *anl2) {
int count1, count2;
count1 = count_actions_covered(anl1);
count2 = count_actions_covered(anl2);
if (count1 < count2) return 1;
if (count1 > count2) return -1;
return 0;
}
#line 444 "inform7/Chapter 24/Action Name Lists.w"
int 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->parity == -1) parity = FALSE;
if ((anl->action_listed) && (k < infinity)) k++; else k = infinity;
}
if (parity == FALSE) k = infinity-k;
return k;
}
#line 127 "inform7/Chapter 24/Action Patterns.w"
action_pattern Plugins__Actions__Patterns__new(void) {
action_pattern ap;
ap.word_ref1 = -1; ap.word_ref2 = -1;
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.named = NULL;
ap.when = NULL;
ap.presence_spec = NULL;
ap.AP_parity = 1;
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 = Code__Chronology__TimePeriods__new();
ap.optional_clauses = NULL;
ap.chief_action_owner_id = 0;
ap.has_substance_other_than_wh = TRUE;
return ap;
}
ap_optional_clause *apoc_new(stacked_variable *stv, specification *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 ap_add_optional_clause(action_pattern *ap, ap_optional_clause *apoc) {
int oid = Code__StackedVariables__get_owner_id(apoc->stv_to_match);
int off = Code__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 = Code__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 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) ||
(Code__StackedVariables__get_offset(apoc->stv_to_match) >= 5))
n++;
}
return n;
}
int compare_specificity_of_apoc_list(action_pattern *ap1, action_pattern *ap2) {
int rct1 = ap_count_optional_clauses(ap1);
int rct2 = ap_count_optional_clauses(ap2);
int off1, off2;
ap_optional_clause *apoc1, *apoc2;
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;
apoc1 = ap1->optional_clauses; apoc2 = ap2->optional_clauses;
while ((apoc1) && (apoc2)) {
off1 = Code__StackedVariables__get_offset(apoc1->stv_to_match);
off2 = Code__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 Plugins__Actions__Patterns__log(action_pattern *ap) {
if (ap == NULL) LOG(" [Null]");
else {
if (ap->valid != TRUE) LOG(" [Invalid]");
else LOG(" [Valid]");
if (ap->named) LOG(" Named:'$W'", ap->named->word_ref1, ap->named->word_ref2);
LOG(" Action: ");
if (ap->action == NULL) LOG("unspecified");
else Plugins__Actions__Lists__log_briefly(ap->action);
if (ap->noun_spec) LOG(" Noun: $S", ap->noun_spec);
if (ap->second_spec) LOG(" Second: $S", ap->second_spec);
if (ap->from_spec) LOG(" From: $S", ap->from_spec);
if (ap->to_spec) LOG(" To: $S", ap->to_spec);
if (ap->by_spec) LOG(" By: $S", ap->by_spec);
if (ap->through_spec) LOG(" Through: $S", ap->through_spec);
if (ap->pushing_spec) LOG(" Pushing: $S", ap->pushing_spec);
if (ap->room_spec) LOG(" Room: $S", ap->room_spec);
if (ap->parameter_spec) LOG(" Parameter: $S", ap->parameter_spec);
if (ap->presence_spec) LOG(" Presence: $S", ap->presence_spec);
if (ap->nowhere_flag) LOG(" Nowhere ");
if (ap->when)
LOG(" When: $S ", ap->when);
if (Code__Chronology__TimePeriods__is_valid(&(ap->duration)))
LOG(" Duration: $t ", &(ap->duration));
}
LOG("\n");
}
action_pattern *ap_store(action_pattern ap) {
action_pattern *sap = CREATE(action_pattern);
*sap = ap;
return sap;
}
int Plugins__Actions__Patterns__is_named(action_pattern *ap) {
if (ap == NULL) return FALSE;
if (ap->named == NULL) return FALSE;
return TRUE;
}
int Plugins__Actions__Patterns__is_valid(action_pattern *ap) {
if (ap == NULL) return FALSE;
return ap->valid;
}
int ap_is_substantial(action_pattern *ap) {
if (ap == NULL) return FALSE;
return ap->has_substance_other_than_wh;
}
int Plugins__Actions__Patterns__is_request(action_pattern *ap) {
if (ap == NULL) return FALSE;
return ap->request;
}
int Plugins__Actions__Patterns__within_action_context(action_pattern *ap, action_name *an) {
action_name_list *anl;
if (ap == NULL) return TRUE;
if (ap->named) return Plugins__Actions__Patterns__Named__within_action_context(ap->named, an);
if (ap->action == NULL) return TRUE;
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 *Plugins__Actions__Patterns__list(action_pattern *ap) {
if (ap == NULL) return NULL;
return ap->action;
}
action_name *Plugins__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 Plugins__Actions__Patterns__object_based(action_pattern *ap) {
if ((ap) && ((ap->action) || (ap->named))) return TRUE;
return FALSE;
}
int Plugins__Actions__Patterns__is_unspecific(action_pattern *ap) {
if (Plugins__Actions__Patterns__required_action(ap) == NULL) return TRUE;
if (ap_clause_is_unspecific(ap->noun_spec)) return TRUE;
if (ap_clause_is_unspecific(ap->second_spec)) return TRUE;
if (ap_clause_is_unspecific(ap->actor_spec)) return TRUE;
return FALSE;
}
int ap_clause_is_unspecific(specification *spec) {
if (spec == NULL) return FALSE;
if (Specifications__species_is(spec, DESCRIPTION_SPC) == FALSE) return FALSE;
return TRUE;
}
int Plugins__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;
return FALSE;
}
void Plugins__Actions__Patterns__coerce_TEST_ACTION_to_TRY_ACTION(specification *spec, action_pattern *ap) {
Specifications__Commands__coerce_TEST_ACTION_to_TRY_ACTION(spec,
ap->noun_spec, ap->second_spec, ap->actor_spec,
ap->request, ap->action);
}
void Plugins__Actions__Patterns__suppress_action_testing(action_pattern *ap) {
if (Code__Chronology__TimePeriods__is_valid(&(ap->duration)) == FALSE) ap->test_anl = FALSE;
}
#line 369 "inform7/Chapter 24/Action Patterns.w"
void Plugins__Actions__Patterns__categorise_as(action_pattern *ap, int w1, int w2) {
LOGIF(ACTION_PATTERN_PARSING, "Categorising the action:\n$A...as $W\n",
ap, w1, w2);
if (ap->actor_spec) {
Problems__sentence_problem(_P_(C24NamedAPWithActor),
"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;
}
Plugins__Actions__Patterns__Named__add(ap, w1, w2);
}
#line 394 "inform7/Chapter 24/Action Patterns.w"
specification *last_spec_failing_to_validate = NULL;
kind *last_kind_failing_to_validate = NULL;
kind *last_kind_found_failing_to_validate = NULL;
void Plugins__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 Plugins__Actions__Patterns__get_validation_case(specification **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 Plugins__Actions__Patterns__suspend_validation(int state) {
ap_validation_suspended = state;
}
int Plugins__Actions__Patterns__validate_parameter(specification *spec, kind *K) {
specification *vts;
kind *kind_found = NULL;
if (spec == NULL) return TRUE;
LOGIF(ACTION_PATTERN_PARSING, "Validating parameter in action pattern: $S ($u)\n",
spec, K);
if (Specifications__is_UNKNOWN(spec)) goto DontValidate;
if (Specifications__is_generic(spec)) return FALSE;
if (ap_validation_suspended) return TRUE;
Specifications__Matching__check_without_expectations(spec); /* to force a generic return kind to be evaluated */
kind_found = Specifications__evaluates_to(spec);
if ((Kinds__get_construct(kind_found) == CON_property) && (Kinds__le(K, K_object)))
return TRUE;
if ((Kinds__eq(kind_found, K_snippet)) && (Kinds__eq(K, K_understanding)))
return TRUE;
if ((Kinds__eq(K, K_understanding)) && (Specifications__species_is(spec, CONSTANT_SPC) == FALSE) &&
(Kinds__eq(kind_found, K_text)))
goto DontValidate;
vts = Specifications__Values__new_generic_CONSTANT(K);
if (Specifications__Matching__can_we_match_value_descriptions(spec, vts) == NEVER_MATCH) {
if ((Kinds__eq(K, K_understanding)) && (Specifications__species_is(spec, CONSTANT_SPC))) {
vts = Specifications__Values__new_actual_CONSTANT(K_snippet);
if (Specifications__Matching__can_we_match_value_descriptions(spec, vts) != NEVER_MATCH) return TRUE;
}
if (Kinds__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 = Specifications__copy(spec);
last_kind_failing_to_validate = K;
last_kind_found_failing_to_validate = kind_found;
return FALSE;
}
int Plugins__Actions__Patterns__validate_when(specification *spec) {
specification *cond_t = Specifications__Conditions__new_generic_CONDITION();
LOGIF(ACTION_PATTERN_PARSING, "Validating 'when' clause in action pattern: $S\n", spec);
if (spec == NULL) return TRUE;
if (Specifications__is_UNKNOWN(spec)) return FALSE;
if (Specifications__Matching__check(spec, cond_t) == NEVER_MATCH) return FALSE;
return TRUE;
}
specification *nullify_nonspecific_references(specification *spec) {
if (spec == NULL) return spec;
if (Specifications__is_UNKNOWN(spec)) return NULL;
return spec;
}
int Plugins__Actions__Patterns__check_going(specification *spec, char *keyword,
kind *ka, kind *kb) {
if (spec == NULL) return TRUE;
if (Specifications__describes_an_object_vaguely_or_exactly(spec)) {
instance *oref = Specifications__object_exactly_described_if_any(spec);
if ((oref == NULL) || (ka == NULL) || (Data__Instances__of_kind(oref, ka)) ||
((kb) && (Data__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, Data__Instances__kind(oref));
if (kb) Problems__quote_kind(6, kb);
Problems__handmade_problem(_P_(C24GoingWrongKind));
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_words(2, spec->word_ref1, spec->word_ref2);
Problems__quote_text(3, keyword);
Problems__handmade_problem(_P_(C24GoingWithoutObject));
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 514 "inform7/Chapter 24/Action Patterns.w"
action_pattern Plugins__Actions__Patterns__parse_parametric(int aw1, int aw2, kind *K) {
action_pattern ap = Plugins__Actions__Patterns__new();
ap.parameter_spec = parse_action_parameter(aw1, aw2);
ap.parameter_kind = K;
ap.valid = Plugins__Actions__Patterns__validate_parameter(ap.parameter_spec, K);
return ap;
}
#line 525 "inform7/Chapter 24/Action Patterns.w"
specification *parse_action_parameter(int w1, int w2) {
if (parse_nt_against_word_range(action_parameter_NTM, w1, w2, NULL, NULL)) return most_recent_result_p;
return Specifications__Unknown__new(w1, w2);
}
specification *parse_verified_action_parameter(int w1, int w2) {
specification *spec = parse_action_parameter(w1, w2);
if (Specifications__is_UNKNOWN(spec)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C24BadOptionalAPClause));
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 552 "inform7/Chapter 24/Action Patterns.w"
int suppress_ap_parsing = FALSE;
int last_successful_w1 = -1, last_successful_w2 = -1;
int prevailing_ap_tense = IS_TENSE;
#line 593 "inform7/Chapter 24/Action Patterns.w"
int action_pattern_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 600 "inform7/Chapter 24/Action Patterns.w"
#line 607 "inform7/Chapter 24/Action Patterns.w"
int we_are_action_pattern_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 617 "inform7/Chapter 24/Action Patterns.w"
int action_pattern_negated_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 628 "inform7/Chapter 24/Action Patterns.w"
int action_pattern_past_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 636 "inform7/Chapter 24/Action Patterns.w"
int action_pattern_past_negated_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 644 "inform7/Chapter 24/Action Patterns.w"
#line 658 "inform7/Chapter 24/Action Patterns.w"
int action_pattern_core_actor_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 661 "inform7/Chapter 24/Action Patterns.w"
#line 677 "inform7/Chapter 24/Action Patterns.w"
int actor_description_NTMR(int w1, int w2, int *X, void **XP) {
#line 678 "inform7/Chapter 24/Action Patterns.w"
if (permit_trying_omission) {
int i, j, k, bl = 0;
for (i=w1+1; i<=w2; i++) {
if (Text__word(i) == OPENBRACKET_V) bl++;
if (Text__word(i) == CLOSEBRACKET_V) bl--;
if ((bl == 0) && (parse_nt_against_word_range(probable_participle_NTM, i, i, NULL, NULL))) {
specification *try_stem = NULL;
instance *I;
int old_state = Plugins__Actions__Patterns__suppress();
if (parse_nt_against_word_range(action_parameter_NTM, w1, i-1, NULL, NULL)) try_stem = most_recent_result_p;
Plugins__Actions__Patterns__resume(old_state);
for (j=w1, k=0; j<=i-1; j++)
if (Text__Vocabulary__test_flags(j, ING_MC)) k++;
if (k>0) continue;
I = Specifications__Values__instance_of_CONSTANT_object_if_any(try_stem);
if (Data__Instances__full_name_includes(I, Text__word(i))) continue;
if ((Specifications__Storage__get_storage_form(try_stem) == LOCAL_VARIABLE_SPC) ||
(Specifications__Storage__get_storage_form(try_stem) == NONLOCAL_VARIABLE_SPC) ||
(Specifications__species_is(try_stem, CONSTANT_SPC)) ||
(Specifications__species_is(try_stem, DESCRIPTION_SPC))) {
*XP = try_stem;
return i-1;
}
}
}
}
return 0;
}
#line 710 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__suppress(void) {
int old_state = suppress_ap_parsing;
suppress_ap_parsing = TRUE;
return old_state;
}
void Plugins__Actions__Patterns__resume(int old_state) {
suppress_ap_parsing = old_state;
}
#line 741 "inform7/Chapter 24/Action Patterns.w"
int action_pattern_core_NTMR(int w1, int w2, int *X, void **XP) {
#line 742 "inform7/Chapter 24/Action Patterns.w"
if (suppress_ap_parsing) return FALSE;
action_pattern *ap = ap_parse_inner(w1, w2, IS_TENSE);
if (ap) { *XP = ap; return TRUE; }
return FALSE;
}
int action_pattern_past_core_NTMR(int w1, int w2, int *X, void **XP) {
#line 749 "inform7/Chapter 24/Action Patterns.w"
if (suppress_ap_parsing) return FALSE;
action_pattern *ap = ap_parse_inner(w1, w2, HASBEEN_TENSE);
if (ap) { *XP = ap; return TRUE; }
return FALSE;
}
#line 765 "inform7/Chapter 24/Action Patterns.w"
int action_pronominal_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 767 "inform7/Chapter 24/Action Patterns.w"
#line 771 "inform7/Chapter 24/Action Patterns.w"
action_pattern *ap_parse_inner(int w1, int w2, int tense) {
if ((w1<0) || (w2<w1)) internal_error("PAP on illegal word range");
unsigned int d = Text__Vocabulary__disjunction_of_flags(w1, w2);
if (((tense == IS_TENSE) && ((d & (ING_MC+NAMED_AP_MC)) == 0))) {
pap_failure_reason = NOPARTICIPLE_PAPF;
return NULL;
}
LOGIF(ACTION_PATTERN_PARSING, "Parse action pattern (tense %d): $W\n", tense, w1, w2);
int duration_set = FALSE;
time_period duration = Code__Chronology__TimePeriods__parse(w1, w2);
if (Code__Chronology__TimePeriods__is_valid(&duration)) {
w2 = Code__Chronology__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 (parse_nt_against_word_range(action_pronominal_NTM, w1, w2, NULL, NULL)) {
if (last_successful_w1 >= 0) {
LOGIF(ACTION_PATTERN_PARSING, "Doing it refers to $W\n", w1, w2);
if (parse_nt_against_word_range(ap_common_core_NTM, last_successful_w1, last_successful_w2, NULL, NULL))
ap = most_recent_result_p;
}
} else {
if (parse_nt_against_word_range(ap_common_core_NTM, w1, w2, NULL, NULL)) {
ap = most_recent_result_p;
last_successful_w1 = w1; last_successful_w2 = w2;
LOGIF(ACTION_PATTERN_PARSING, "Last successful w1,w2 set to: $W\n",
last_successful_w1, last_successful_w2);
}
}
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 814 "inform7/Chapter 24/Action Patterns.w"
int ap_common_core_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 819 "inform7/Chapter 24/Action Patterns.w"
#line 825 "inform7/Chapter 24/Action Patterns.w"
int condition_in_ap_NTMR(int w1, int w2, int *X, void **XP) {
#line 826 "inform7/Chapter 24/Action Patterns.w"
ph_stack_frame *phsf = NULL;
if (Code__Frames__current_stack_frame() == NULL) phsf = Code__Frames__new_nonphrasal();
Code__StackedVariables__Owners__Lists__append(
Code__Frames__get_stvol(),
all_nonempty_stacked_action_vars);
LOGIF(ACTION_PATTERN_PARSING, "A when clause <$W> is suspected.\n", w1, w2);
specification *wts = NULL;
int s = pap_failure_reason;
if (parse_nt_against_word_range(spec_condition_NTM, w1, w2, NULL, NULL)) wts = most_recent_result_p;
pap_failure_reason = s;
if (phsf) Code__Frames__remove_nonphrase_stack_frame();
if ((wts) && (Plugins__Actions__Patterns__validate_when(wts))) {
*XP = wts;
return TRUE;
}
return FALSE;
}
#line 847 "inform7/Chapter 24/Action Patterns.w"
int ap_common_core_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 850 "inform7/Chapter 24/Action Patterns.w"
#line 862 "inform7/Chapter 24/Action Patterns.w"
int ap_common_core_inner_inner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 880 "inform7/Chapter 24/Action Patterns.w"
if (Plugins__Actions__Patterns__validate_parameter(RP[1], K_object) == FALSE)
return FALSE; /* the "room" isn't even an object */
action_pattern ap = Plugins__Actions__Patterns__new();
ap.valid = TRUE; ap.word_ref1 = w1; ap.word_ref2 = w2;
ap.room_spec = RP[1];
*XP = ap_store(ap);
}
#line 863 "inform7/Chapter 24/Action Patterns.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 890 "inform7/Chapter 24/Action Patterns.w"
action_pattern ap = Plugins__Actions__Patterns__new();
ap.valid = TRUE; ap.word_ref1 = w1; ap.word_ref2 = w2;
ap.named = RP[1];
*XP = ap_store(ap);
}
#line 864 "inform7/Chapter 24/Action Patterns.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 898 "inform7/Chapter 24/Action Patterns.w"
if (Plugins__Actions__Patterns__validate_parameter(RP[2], K_object) == FALSE)
return FALSE; /* the "room" isn't even an object */
action_pattern ap = Plugins__Actions__Patterns__new();
ap.valid = TRUE; ap.word_ref1 = w1; ap.word_ref2 = w2;
ap.named = RP[1]; ap.room_spec = RP[2];
*XP = ap_store(ap);
}
#line 865 "inform7/Chapter 24/Action Patterns.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 867 "inform7/Chapter 24/Action Patterns.w"
int named_action_pattern_NTMR(int w1, int w2, int *X, void **XP) {
#line 869 "inform7/Chapter 24/Action Patterns.w"
named_action_pattern *nap = Plugins__Actions__Patterns__Named__by_name(w1, w2);
if (nap) {
*XP = nap;
return TRUE;
}
return FALSE;
}
#line 915 "inform7/Chapter 24/Action Patterns.w"
int ap_common_core_inner_inner_inner_NTMR(int w1, int w2, int *X, void **XP) {
#line 916 "inform7/Chapter 24/Action Patterns.w"
if (scanning_anl_only_mode) {
action_name_list *anl = Plugins__Actions__Lists__parse(w1, w2, prevailing_ap_tense);
if (anl == NULL) return FALSE;
action_pattern ap = Plugins__Actions__Patterns__new(); ap.valid = TRUE;
ap.word_ref1 = w1; ap.word_ref2 = w2;
ap.action = anl;
*XP = ap_store(ap);
return TRUE;
} else {
action_pattern ap = parse_action_pattern_dash(w1, w2);
if ((Plugins__Actions__Patterns__is_valid(&ap)) && (ap_is_substantial(&ap))) {
*XP = ap_store(ap); return TRUE;
}
}
return FALSE;
}
#line 939 "inform7/Chapter 24/Action Patterns.w"
int action_operand_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 943 "inform7/Chapter 24/Action Patterns.w"
int going_action_irregular_operand_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 947 "inform7/Chapter 24/Action Patterns.w"
int understanding_action_irregular_operand_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 951 "inform7/Chapter 24/Action Patterns.w"
#line 956 "inform7/Chapter 24/Action Patterns.w"
int action_parameter_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 976 "inform7/Chapter 24/Action Patterns.w"
specification *spec = RP[1];
if (Specifications__Values__is_generic_CONSTANT(spec))
Specifications__Conditions__coerce_generic_CONSTANT_to_DESCRIPTION(spec);
*XP = spec;
}
#line 959 "inform7/Chapter 24/Action 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 960 "inform7/Chapter 24/Action Patterns.w"
#line 965 "inform7/Chapter 24/Action Patterns.w"
int spec_local_variable_NTMR(int w1, int w2, int *X, void **XP) {
#line 966 "inform7/Chapter 24/Action Patterns.w"
local_variable *lvar = Code__LocalVariables__parse(Code__Frames__current_stack_frame(), w1, w2);
if (lvar) {
*XP = Specifications__Storage__new_LOCAL_VARIABLE(w1, w2, lvar); return TRUE;
}
return FALSE;
}
#line 984 "inform7/Chapter 24/Action Patterns.w"
action_pattern parse_action_pattern_dash(int w1, int w2) {
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 = Plugins__Actions__Patterns__new(); ap.valid = FALSE;
ap.word_ref1 = w1; ap.word_ref2 = w2;
LOGIF(ACTION_PATTERN_PARSING, "PAR after preamble: $W\n", w1, w2);
{
#line 1042 "inform7/Chapter 24/Action Patterns.w"
action_name_list *preliminary_anl =
Plugins__Actions__Lists__parse(w1, w2, tense);
action_name *chief_an =
Plugins__Actions__Lists__get_single_action(preliminary_anl);
if (chief_an == NULL) {
int x;
chief_an = Plugins__Actions__longest_null(w1, w2, tense, &x);
}
if (chief_an) {
stacked_variable *last_stv_specified = NULL;
i = w1+1; j = -1;
LOGIF(ACTION_PATTERN_PARSING, "Trying special clauses at <$W> = %d, %d\n", i, w2, i, w2);
while (i < w2) {
stacked_variable *stv = NULL;
if (Text__unexpectedly_upper_case(i) == FALSE)
stv = Plugins__Actions__parse_match_clause(chief_an, i, w2);
if (stv != NULL) {
LOGIF(ACTION_PATTERN_PARSING,
"Special clauses found on <$W> with %d, %d, %d\n",
i, w2, i, j, k);
if (last_stv_specified == NULL) j = i-1;
else ap_add_optional_clause(&ap,
apoc_new(last_stv_specified, parse_verified_action_parameter(k, i-1)));
k = i+1;
last_stv_specified = stv;
}
i++;
}
if (last_stv_specified != NULL)
ap_add_optional_clause(&ap,
apoc_new(last_stv_specified, parse_verified_action_parameter(k, w2)));
if (j >= 0) w2 = j;
}
}
#line 995 "inform7/Chapter 24/Action Patterns.w"
;
{
#line 1081 "inform7/Chapter 24/Action Patterns.w"
anl = Plugins__Actions__Lists__parse(w1, w2, tense);
if (anl == NULL) goto Failed;
LOGIF(ACTION_PATTERN_PARSING, "ANL from PAR(i):\n$L\n", anl);
}
#line 996 "inform7/Chapter 24/Action Patterns.w"
;
{
#line 1103 "inform7/Chapter 24/Action Patterns.w"
int no_positions = 0;
int position_at[MAX_AP_POSITIONS], position_min_parc[MAX_AP_POSITIONS];
{
#line 1135 "inform7/Chapter 24/Action Patterns.w"
action_name_list *entry;
for (entry = anl; entry; entry = entry->next) {
int pos = -1;
{
#line 1147 "inform7/Chapter 24/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 1138 "inform7/Chapter 24/Action Patterns.w"
;
if ((position_min_parc[pos] == UNTHINKABLE_POSITION) ||
(entry->parc < position_min_parc[pos]))
position_min_parc[pos] = entry->parc;
}
}
#line 1105 "inform7/Chapter 24/Action Patterns.w"
;
{
#line 1161 "inform7/Chapter 24/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 1106 "inform7/Chapter 24/Action Patterns.w"
;
{
#line 1174 "inform7/Chapter 24/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]++;
else internal_error("minimum parc out of range");
}
if ((positions_with_min_parc[1] > 1) ||
(positions_with_min_parc[2] > 1)) {
failure_this_call = MIXEDNOUNS_PAPF; goto Failed;
}
}
#line 1107 "inform7/Chapter 24/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) {
{
#line 1190 "inform7/Chapter 24/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 (entry->parameter_w1[0] >= 0) {
int p1 = entry->parameter_w1[0], p2 = entry->parameter_w2[0];
if ((entry->action_listed == going_action) && (parse_nt_against_word_range(going_action_irregular_operand_NTM, p1, p2, NULL, NULL))) {
if (most_recent_result == FALSE) trial_ap.nowhere_flag = TRUE;
else trial_ap.nowhere_flag = 2;
} else put_action_object_into_ap(&trial_ap, 1, p1, p2);
}
}
int pw1 = entry->parameter_w1[1], pw2 = entry->parameter_w2[1];
if (entry->parc >= 2) {
if (pw1 >= 0) {
if ((entry->action_listed != NULL)
&& (Kinds__eq(Plugins__Actions__get_data_type_of_second_noun(entry->action_listed), K_understanding))
&& (parse_nt_against_word_range(understanding_action_irregular_operand_NTM, pw1, pw2, NULL, NULL))) {
trial_ap.second_spec = Specifications__Values__new_actual_CONSTANT(K_understanding);
trial_ap.second_spec->word_ref1 = entry->parameter_w1[1];
trial_ap.second_spec->word_ref2 = entry->parameter_w1[1];
} else {
put_action_object_into_ap(&trial_ap, 2, pw1, pw2);
}
}
}
if (entry->in_w1 >= 0)
put_action_object_into_ap(&trial_ap, 3, entry->in_w1, entry->in_w2);
}
#line 1114 "inform7/Chapter 24/Action Patterns.w"
;
{
#line 1222 "inform7/Chapter 24/Action Patterns.w"
kind *check_n = K_object;
kind *check_s = K_object;
if (entry->action_listed != NULL) {
check_n = Plugins__Actions__get_data_type_of_noun(entry->action_listed);
check_s = Plugins__Actions__get_data_type_of_second_noun(entry->action_listed);
}
trial_ap.valid = TRUE;
if ((trial_ap.noun_any == FALSE) &&
(Plugins__Actions__Patterns__validate_parameter(trial_ap.noun_spec, check_n) == FALSE))
trial_ap.valid = FALSE;
if ((trial_ap.second_any == FALSE) &&
(Plugins__Actions__Patterns__validate_parameter(trial_ap.second_spec, check_s) == FALSE))
trial_ap.valid = FALSE;
if ((trial_ap.room_any == FALSE) &&
(Plugins__Actions__Patterns__validate_parameter(trial_ap.room_spec, K_object) == FALSE))
trial_ap.valid = FALSE;
}
#line 1115 "inform7/Chapter 24/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 1242 "inform7/Chapter 24/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 1126 "inform7/Chapter 24/Action Patterns.w"
;
LOGIF(ACTION_PATTERN_PARSING, "List after action winnowing:\n$L\n", anl);
}
#line 997 "inform7/Chapter 24/Action Patterns.w"
;
{
#line 1265 "inform7/Chapter 24/Action Patterns.w"
int immiscible = FALSE;
action_name *first = anl->action_listed;
int no_with_pars = 0, no_oow = 0, no_iw = 0;
action_name_list *entry;
for (entry = anl; entry; entry = entry->next) {
action_name *this = entry->action_listed;
int max = 1000000;
if (this) max = Plugins__Actions__get_max_parameters(this);
if (first == NULL) max = 1;
if (anl->parc > max) immiscible = TRUE;
if ((this) && (Plugins__Actions__is_out_of_world(this))) no_oow++; else no_iw++;
if (entry->parc == 0) continue;
no_with_pars++;
if ((first) && (this) && (Kinds__eq(
Plugins__Actions__get_data_type_of_noun(first),
Plugins__Actions__get_data_type_of_noun(this)) == FALSE))
immiscible = TRUE;
if (entry->parc == 1) continue;
if ((first) && (this) && (Kinds__eq(
Plugins__Actions__get_data_type_of_second_noun(first),
Plugins__Actions__get_data_type_of_second_noun(this)) == FALSE))
immiscible = TRUE;
}
if (no_with_pars > 1) immiscible = TRUE;
if ((no_oow > 0) && (no_iw > 0)) immiscible = TRUE;
if (immiscible) {
failure_this_call = IMMISCIBLE_PAPF;
goto Failed;
}
}
#line 998 "inform7/Chapter 24/Action Patterns.w"
;
{
#line 1010 "inform7/Chapter 24/Action Patterns.w"
pap_failure_reason = 0;
ap.word_ref1 = w1; ap.word_ref2 = w2;
ap.action = anl;
if ((anl != NULL) && (anl->action_listed == NULL)) ap.action = NULL;
ap.valid = TRUE;
ap.actor_spec = nullify_nonspecific_references(ap.actor_spec);
ap.noun_spec = nullify_nonspecific_references(ap.noun_spec);
ap.second_spec = nullify_nonspecific_references(ap.second_spec);
ap.room_spec = nullify_nonspecific_references(ap.room_spec);
int ch = Config__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 999 "inform7/Chapter 24/Action Patterns.w"
;
return ap;
Failed: ;
{
#line 1031 "inform7/Chapter 24/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", w1, w2);
}
#line 1003 "inform7/Chapter 24/Action Patterns.w"
;
return ap;
}
#line 1303 "inform7/Chapter 24/Action Patterns.w"
int 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 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 Plugins__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 ((Code__Chronology__TimePeriods__is_valid(&(ap->duration))) || (ap->when))
c++;
if (ap->parameter_spec) c++;
return c;
}
int Plugins__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 = ap_count_going(ap1); rct2 = 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 = ap_count_rooms(ap1); rct2 = 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 = 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 = Plugins__Actions__Lists__compare_specificity(ap1->action, ap2->action);
if (rv != 0) return rv;
c_s_stage_law = "III.5.1 - Action/When/Duration";
rv = Code__Chronology__TimePeriods__compare_specificity(&(ap1->duration), &(ap2->duration));
if (rv != 0) return rv;
c_s_stage_law = "III.5.2 - Action/When/Circumstances";
rv = Specifications__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 ((ap1->named != NULL) && (ap2->named == NULL))
return 1;
if ((ap1->named == NULL) && (ap2->named != NULL))
return -1;
return 0;
}
#line 1464 "inform7/Chapter 24/Action Patterns.w"
void put_action_object_into_ap(action_pattern *ap, int pos, int w1, int w2) {
specification *spec = NULL;
int any_flag = FALSE;
if (parse_nt_against_word_range(action_operand_NTM, w1, w2, NULL, NULL)) {
if (most_recent_result) spec = most_recent_result_p;
else { any_flag = TRUE; spec = Specifications__Values__new_generic_CONSTANT(K_thing); }
}
if (spec == NULL) spec = Specifications__Unknown__new(w1, w2);
if (Specifications__Values__is_CONSTANT_of_kind(spec, K_text))
Specifications__set_kind_of_value(spec, K_understanding);
if (Specifications__Values__is_generic_CONSTANT(spec))
Specifications__Conditions__coerce_generic_CONSTANT_to_DESCRIPTION(spec);
spec->word_ref1 = w1; spec->word_ref2 = w2;
LOGIF(ACTION_PATTERN_PARSING, "PAOIA (position %d) $W = $S\n", pos, w1, w2, 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 1494 "inform7/Chapter 24/Action Patterns.w"
int CAP_insert_clause(int f, OUTPUT_STREAM, char *i6_condition) {
if (f) WRITE(" && ");
WRITE("(%s)", i6_condition);
return TRUE;
}
#line 1520 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__compile_pattern_match_clause(int f,
OUTPUT_STREAM, nonlocal_variable *I6_global_variable,
specification *spec, kind *verify_as_kind, int adapt_region) {
specification *I6_var_TS;
int force_proposition = FALSE;
if (spec == NULL) return f;
LOGIF(ACTION_PATTERN_COMPILATION, "[MPE on $Z: $S]\n", I6_global_variable, spec);
I6_var_TS = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(I6_global_variable);
if (f) WRITE(" && ");
int c1, c2;
Specifications__Conditions__get_calling(spec, &c1, &c2);
if (c1 >= 0) {
local_variable *lvar =
Code__LocalVariables__ensure_called_local(c1, c2,
Specifications__Conditions__get_described_kind(spec));
Code__LocalVariables__add_calling_to_condition(lvar);
WRITE("(%s = %s, (",
Code__LocalVariables__lvalue(lvar),
Data__NonlocalVariables__identifier(I6_global_variable));
}
force_proposition = TRUE;
if (Specifications__is_UNKNOWN(spec)) {
if (problem_count == 0) internal_error("MPE found unknown SP");
force_proposition = FALSE;
}
else if (Specifications__family_is(spec, STORAGE_FMY)) {
force_proposition = TRUE;
if (Specifications__species_is(spec, TABLE_ENTRY_SPC)) {
if (Specifications__get_argc(spec) != 2) internal_error("MPE with bad no of args");
Code__LocalVariables__add_table_lookup();
WRITE("(ct_1=ExistsTableRowCorr(ct_0=");
Specifications__compile(OUT, Specifications__get_argument(spec, 1));
WRITE(",");
Specifications__compile(OUT, Specifications__get_argument(spec, 0));
WRITE(",");
Specifications__compile(OUT, I6_var_TS);
WRITE("))");
force_proposition = FALSE;
}
}
else if (Specifications__family_is(spec, VALUE_FMY)) {
if (Specifications__Values__is_generic_CONSTANT(spec)) {
WRITE("(true)");
force_proposition = FALSE;
}
if (Specifications__Values__is_CONSTANT_of_kind(spec, K_understanding)) {
if ((parse_nt_against_word_range(understanding_action_irregular_operand_NTM, spec->word_ref1, spec->word_ref2, NULL, NULL)) &&
(most_recent_result == TRUE))
WRITE("(true)");
else {
WRITE("(");
Specifications__compile(OUT, spec);
WRITE("(consult_from, consult_words)~=GPR_FAIL)");
}
force_proposition = FALSE;
}
if ((I6_global_variable != parameter_object_VAR) &&
(Specifications__Values__is_CONSTANT_object(spec))) {
instance *I = Specifications__object_exactly_described_if_any(spec);
if ((I) && (Data__Instances__of_kind(I, K_region))) {
LOGIF(ACTION_PATTERN_PARSING,
"$S on $u : $T\n", spec, verify_as_kind, current_sentence);
if (adapt_region) {
LOG("Yep\n", verify_as_kind);
WRITE("(TestRegionalContainment(");
Specifications__compile(OUT, I6_var_TS);
WRITE(",");
Specifications__compile(OUT, spec);
WRITE("))");
force_proposition = FALSE;
}
}
}
}
else if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
if ((I6_global_variable != parameter_object_VAR) &&
((Specifications__Conditions__get_described_instance(spec)) &&
(adapt_region) &&
(Data__Instances__of_kind(Specifications__Conditions__get_described_instance(spec), K_region)))) {
WRITE("(TestRegionalContainment(");
Specifications__compile(OUT, I6_var_TS);
WRITE(",");
Specifications__compile(OUT, spec);
WRITE("))");
force_proposition = FALSE;
} else {
Specifications__Conditions__convert_docket_to_proposition(spec);
force_proposition = FALSE;
}
}
pcalc_prop *prop = Specifications__get_proposition(spec);
if (Specifications__family_is(spec, STORAGE_FMY))
LOGIF(ACTION_PATTERN_COMPILATION, "Storage has $D\n", prop);
if ((force_proposition) && (prop == NULL)) {
prop = Calculus__Propositions__from_spec(spec, FALSE);
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__type_check(prop, Calculus__Propositions__tc_no_problem_reporting());
Calculus__Deferrals__compile_test_of_proposition(OUT, I6_var_TS, prop);
}
if (c1 >= 0) WRITE("))");
return TRUE;
}
void Plugins__Actions__Patterns__as_stored_action(OUTPUT_STREAM, action_pattern *ap) {
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 = Plugins__Actions__Lists__get_singleton_action(ap->action);
STREAM_WRITE(BC, "##%s ", Plugins__Actions__identifier(an));
if (ap->noun_spec) {
if (Specifications__Values__is_CONSTANT_of_kind(ap->noun_spec, K_understanding))
Data__Strings__compile_literal(BC, ap->noun_spec->word_ref1);
else Specifications__compile(BC, ap->noun_spec);
} else {
STREAM_WRITE(BC, "0");
}
STREAM_WRITE(BC, " ");
if (ap->second_spec) {
if (Specifications__Values__is_CONSTANT_of_kind(ap->second_spec, K_understanding))
Data__Strings__compile_literal(BC, ap->second_spec->word_ref1);
else Specifications__compile(BC, ap->second_spec);
} else {
STREAM_WRITE(BC, "0");
}
STREAM_WRITE(BC, " ");
if (ap->actor_spec)
Specifications__compile(BC, ap->actor_spec);
else
STREAM_WRITE(BC, "selfobj");
STREAM_WRITE(BC, " ");
STREAM_WRITE(BC, "%d ", ap->request);
STREAM_WRITE(BC, "0");
Kinds__RunTime__end_block_constant(K_stored_action);
}
void Plugins__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 (Code__Chronology__TimePeriods__is_valid(&(ap.duration))) {
Code__Chronology__compile_past_action_pattern(OUT, ap.duration, ap);
} else {
int par = ap.AP_parity;
Code__LocalVariables__begin_condition(OUT);
if (par == -1) WRITE("(~~(");
if (ap.named != NULL) {
if (f) WRITE(" && ");
WRITE("(%s())", Plugins__Actions__Patterns__Named__identifier(ap.named));
f = TRUE;
}
if (Plugins__Actions__Lists__negated(ap.action)) {
{
#line 1839 "inform7/Chapter 24/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 = Specifications__Storage__get_nonlocal_variable_if_any(ap.actor_spec);
if ((var) && (var == player_VAR)) impose = FALSE;
instance *I = Specifications__Values__instance_of_CONSTANT_object_if_any(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 = Plugins__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 1696 "inform7/Chapter 24/Action Patterns.w"
;
if (f) WRITE(" && ");
WRITE("(~~(");
f = FALSE;
}
if ((ap.action != NULL) && (ap.test_anl)) {
if (f) WRITE(" && ");
Plugins__Actions__Lists__compile(OUT, ap.action);
f = TRUE;
}
if (Plugins__Actions__Lists__negated(ap.action) == FALSE)
{
#line 1839 "inform7/Chapter 24/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 = Specifications__Storage__get_nonlocal_variable_if_any(ap.actor_spec);
if ((var) && (var == player_VAR)) impose = FALSE;
instance *I = Specifications__Values__instance_of_CONSTANT_object_if_any(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 = Plugins__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 1707 "inform7/Chapter 24/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) {
kind_of_noun = Plugins__Actions__get_data_type_of_noun(ap.action->action_listed);
if (kind_of_noun == NULL) kind_of_noun = K_object;
}
if (Kinds__le(kind_of_noun, K_object)) {
f = Plugins__Actions__Patterns__compile_pattern_match_clause(f, OUT, I6_noun_VAR, ap.noun_spec,
kind_of_noun, FALSE);
} else {
f = Plugins__Actions__Patterns__compile_pattern_match_clause(f, OUT,
Data__NonlocalVariables__temporary("parsed_number", kind_of_noun),
ap.noun_spec, kind_of_noun, FALSE);
}
if (ap.action) {
kind_of_noun = Plugins__Actions__get_data_type_of_second_noun(ap.action->action_listed);
if (kind_of_noun == NULL) kind_of_noun = K_object;
}
if (Kinds__le(kind_of_noun, K_object)) {
f = Plugins__Actions__Patterns__compile_pattern_match_clause(f, OUT, I6_second_VAR, ap.second_spec,
kind_of_noun, FALSE);
} else {
f = Plugins__Actions__Patterns__compile_pattern_match_clause(f, OUT,
Data__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 = Plugins__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 = Plugins__Actions__Patterns__compile_pattern_match_clause(f,
OUT, actor_location_VAR, ap.room_spec, K_object, TRUE);
}
}
kind *saved_kind = Data__NonlocalVariables__kind(parameter_object_VAR);
Data__NonlocalVariables__set_kind(parameter_object_VAR, ap.parameter_kind);
f = Plugins__Actions__Patterns__compile_pattern_match_clause(f, OUT,
parameter_object_VAR, ap.parameter_spec, ap.parameter_kind, FALSE);
Data__NonlocalVariables__set_kind(parameter_object_VAR, saved_kind);
apoc = ap.optional_clauses;
while (apoc) {
char lvalue_text[64];
Code__StackedVariables__compile_rvalue_to_text(apoc->stv_to_match, lvalue_text);
kind *K = Code__StackedVariables__get_kind(apoc->stv_to_match);
f = Plugins__Actions__Patterns__compile_pattern_match_clause(f, OUT,
Data__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 = CAP_insert_clause(f, OUT, "(MStack-->MstVON(20007,1)) == nothing");
else {
specification *somewhere = Specifications__Conditions__new_DESCRIPTION();
Specifications__Conditions__set_described_kind(somewhere, K_room);
f = Plugins__Actions__Patterns__compile_pattern_match_clause(f, OUT,
Data__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 = 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("(");
Plugins__Actions__Patterns__compile_pattern_match_clause(FALSE, OUT,
Data__NonlocalVariables__temporary(
Data__Instances__identifier(to_be_present), K_object),
ap.presence_spec, K_object, FALSE);
WRITE("&& (TestScope(%s, actor)))",
Data__Instances__identifier(to_be_present));
} else {
int pc1, pc2;
loop_over_scope *los = Plugins__Actions__ScopeLoops__new(ap.presence_spec);
Specifications__Conditions__get_calling(ap.presence_spec, &pc1, &pc2);
if (pc1 >= 0) {
local_variable *lvar = Code__LocalVariables__ensure_called_local(pc1, pc2,
Specifications__Conditions__get_described_kind(ap.presence_spec));
WRITE("(los_rv=false, LoopOverScope(LOS_%d, actor), %s=los_rv)",
los->allocation_id, Code__LocalVariables__lvalue(lvar));
} else {
WRITE("(los_rv=false, LoopOverScope(LOS_%d, actor), los_rv)",
los->allocation_id);
}
}
f = TRUE;
}
if (Plugins__Actions__Lists__negated(ap.action)) {
if (f == FALSE) WRITE("FALSE");
WRITE("))");
}
if (ap.when != NULL) {
if (f) WRITE(" && ");
WRITE("(self=actor,true) && ");
Specifications__compile(OUT, ap.when);
f = TRUE;
}
if (f == FALSE) WRITE("TRUE");
if (par == -1) WRITE("))");
Code__LocalVariables__end_condition(OUT);
}
}
#line 1872 "inform7/Chapter 24/Action Patterns.w"
int Plugins__Actions__Patterns__refers_to_past(action_pattern *ap) {
if (Code__Chronology__TimePeriods__is_valid(&(ap->duration))) return TRUE;
return FALSE;
}
void Plugins__Actions__Patterns__convert_to_present_tense(action_pattern *ap) {
Code__Chronology__TimePeriods__make_invalid(&(ap->duration));
}
int pta_acceptable(specification *spec) {
instance *I;
if (spec == NULL) return TRUE;
if (Specifications__species_is(spec, DESCRIPTION_SPC) == FALSE) return TRUE;
I = Specifications__object_exactly_described_if_any(spec);
if (I) return TRUE;
return FALSE;
}
int Plugins__Actions__Patterns__makes_callings(action_pattern *ap) {
if (Specifications__Conditions__makes_callings(ap->noun_spec)) return TRUE;
if (Specifications__Conditions__makes_callings(ap->second_spec)) return TRUE;
if (Specifications__Conditions__makes_callings(ap->actor_spec)) return TRUE;
if (Specifications__Conditions__makes_callings(ap->room_spec)) return TRUE;
if (Specifications__Conditions__makes_callings(ap->parameter_spec)) return TRUE;
if (Specifications__Conditions__makes_callings(ap->presence_spec)) return TRUE;
return FALSE;
}
void Plugins__Actions__Patterns__compile_present_tense(OUTPUT_STREAM, action_pattern *ap) {
Plugins__Actions__Patterns__compile_pattern_match(OUT, *ap, FALSE);
}
void Plugins__Actions__Patterns__compile_past_tense(OUTPUT_STREAM, action_pattern *ap) {
int bad_form = FALSE;
WRITE("(");
if (ap->AP_parity == -1) WRITE("~~(");
WRITE("TestActionBitmap(");
if (ap->noun_spec == NULL)
WRITE("nothing");
else
Specifications__compile(OUT, ap->noun_spec);
WRITE(",");
if (ap->action == NULL)
WRITE("-1");
else {
if (ap->action->next) bad_form = TRUE;
if (Plugins__Actions__can_be_compiled_in_past_tense(ap->action->action_listed) == FALSE)
bad_form = TRUE;
WRITE("##%s", Plugins__Actions__identifier(ap->action->action_listed));
}
if (pta_acceptable(ap->noun_spec) == FALSE) bad_form = TRUE;
if (pta_acceptable(ap->second_spec) == FALSE) bad_form = TRUE;
if (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(")");
if (ap->AP_parity == -1) WRITE(")");
WRITE(")");
if (bad_form)
Problems__sentence_problem(_P_(C24PTAPTooComplex),
"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 24 "inform7/Chapter 24/Looping Over Scope.w"
loop_over_scope *Plugins__Actions__ScopeLoops__new(specification *what) {
loop_over_scope *los = CREATE(loop_over_scope);
los->what_to_find = Specifications__Conditions__copy_and_copy_docket(what);
Specifications__Conditions__clear_calling(los->what_to_find);
return los;
}
loop_over_scope *latest_los = NULL;
int Plugins__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 50 "inform7/Chapter 24/Looping Over Scope.w"
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "LOS_%d", los->allocation_id);
OUT = Code__Routines__begin(OUT, i6_routine_identifier);
ph_stack_frame *phsf = Code__Frames__current_stack_frame();
Code__LocalVariables__Pronoun__add(phsf, -1, -1, K_object);
WRITE("if ");
Code__LocalVariables__begin_condition(OUT);
Plugins__Actions__Patterns__compile_pattern_match_clause(FALSE, OUT,
Data__NonlocalVariables__temporary("t_0", K_object),
los->what_to_find, K_object, FALSE);
Code__LocalVariables__end_condition(OUT);
WRITE(" los_rv = t_0;\n");
OUT = Code__Routines__end(OUT);
}
#line 41 "inform7/Chapter 24/Looping Over Scope.w"
;
N++;
}
return N;
}
#line 27 "inform7/Chapter 24/Named Action Patterns.w"
named_action_pattern *nap_new(int w1, int w2) {
named_action_pattern *nap = CREATE(named_action_pattern);
nap->first = NULL;
nap->word_ref1 = w1;
nap->word_ref2 = w2;
Semantics__Nouns__ExcerptMeanings__register(NAMED_AP_MC, 0, w1, w2,
STORE_POINTER_named_action_pattern(nap));
sprintf(nap->nap_I6_identifier, "NAP_%d", nap->allocation_id);
return nap;
}
named_action_pattern *Plugins__Actions__Patterns__Named__by_name(int w1, int w2) {
meaning_list *ml = Parser__SP__parse_excerpt(NAMED_AP_MC, w1, w2);
if (ml) return RETRIEVE_POINTER_named_action_pattern(Semantics__Nouns__ExcerptMeanings__data(Parser__SP__MeaningLists__meaning(ml)));
return NULL;
}
char *Plugins__Actions__Patterns__Named__identifier(named_action_pattern *nap) {
return nap->nap_I6_identifier;
}
void Plugins__Actions__Patterns__Named__add(action_pattern *app, int w1, int w2) {
named_action_pattern *nap;
nap = Plugins__Actions__Patterns__Named__by_name(w1, w2);
if (nap) {
action_pattern *list;
list = nap->first; while (list->next) list = list->next;
list->next = app;
return;
}
nap = nap_new(w1, w2);
nap->first = app;
}
int Plugins__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 (Plugins__Actions__Patterns__within_action_context(ap, an)) return TRUE;
return FALSE;
}
void Plugins__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>");
Text__print_raw_text_to_stream(nap->word_ref1, nap->word_ref2, ifl);
INDEX("</b>");
Index__link(nap->word_ref1);
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;");
Text__print_raw_text_to_stream(ap->word_ref1, ap->word_ref2, ifl);
Index__link(ap->word_ref1);
ap = ap->next;
}
INDEX("</p>\n");
}
}
void Plugins__Actions__Patterns__Named__compile(OUTPUT_STREAM) {
named_action_pattern *nap;
action_pattern *ap;
LOOP_OVER(nap, named_action_pattern) {
OUT = Code__Routines__begin_numbered(OUT, "NAP_%d", nap->allocation_id);
ap = nap->first;
while (ap != NULL) {
WRITE("if (");
Plugins__Actions__Patterns__compile_pattern_match(OUT, *ap, TRUE);
WRITE(") rtrue;\n");
ap = ap->next;
}
WRITE("rfalse;\n");
OUT = Code__Routines__end(OUT);
}
}
#line 39 "inform7/Chapter 24/Actions Index.w"
void 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 Plugins__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 Plugins__Actions__Index__verb_definition(char *p, char *trueverb, int true_verb_wn) {
int i = 1;
if ((p[0] == 0) || (p[1] == 0)) return;
if (trueverb) {
if (strcmp(trueverb, "0") != 0) {
INDEX("%s", trueverb);
if (true_verb_wn != -1)
Plugins__Parsing__Verbs__index_command_aliases(
Plugins__Parsing__Verbs__find_command(true_verb_wn));
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: STREAM_PUT(ifl, c); break;
}
}
}
command_index_entry *Plugins__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 Plugins__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)
Plugins__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:
Plugins__Parsing__Verbs__index_normal(gv, vie->command_headword);
break;
case ALIAS_COMMAND:
Plugins__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 Plugins__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 24/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 *), compare_action_names);
}
#line 156 "inform7/Chapter 24/Actions Index.w"
;
{
#line 165 "inform7/Chapter 24/Actions Index.w"
Formats__HTML__begin_html_table(ifl, NULL, FALSE, 0, 0, 0, 0, 0);
Formats__HTML__first_html_column(ifl, 0);
INDEX("<b>action</b>");
Formats__HTML__next_html_column(ifl, 0);
INDEX("<b>noun</b>");
Formats__HTML__next_html_column(ifl, 0);
INDEX("<b>second noun</b>");
Formats__HTML__end_html_row(ifl);
int i;
for (i=0; i<nr; i++) {
Formats__HTML__first_html_column(ifl, 0);
action_name *an = sorted[i];
if (an->out_of_world) INDEX("<font color=\"#800000\">");
Text__print_text_to_stream(an->word_ref1, an->word_ref2, ifl);
if (an->out_of_world) INDEX("</font>");
Index__detail_link("A", an->allocation_id, TRUE);
if (an->requires_light) INDEX(" <i>requires light</i>");
Formats__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>");
}
Formats__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>");
}
Formats__HTML__end_html_row(ifl);
}
Formats__HTML__end_html_table(ifl);
}
#line 157 "inform7/Chapter 24/Actions Index.w"
;
Memory__I7_free(sorted, INDEX_SORTING_MREASON);
}
}
#line 218 "inform7/Chapter 24/Actions Index.w"
int 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 Text__rangecmp(an1->word_ref1, an1->word_ref2, an2->word_ref1, an2->word_ref2);
}
#line 227 "inform7/Chapter 24/Actions Index.w"
void Plugins__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 = Plugins__Actions__index(an, 1, &ext, &current_area, f, &new_par, FALSE, FALSE);
if (new_par) par_count++;
an->an_index_group = par_count;
}
}
void Plugins__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 = Plugins__Actions__index(an2, 1, &ext, &current_area, f, &new_par, (an2 == an)?TRUE:FALSE, TRUE);
}
INDEX("<p><hr><p>");
Plugins__Actions__index(an, 2, &ext, &current_area, FALSE, &new_par, FALSE, FALSE);
}
}
void Plugins__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>");
Plugins__Parsing__Verbs__index_tokens();
}
#line 98 "inform7/Chapter 24/Activities.w"
sentence_handler NEW_ACTIVITY_SH_handler =
{ SENTENCE_NT, NEW_ACTIVITY_VB, 1, create_activity };
void create_activity(parse_node *pn) {
int w1 = pn->down->next->word_ref1;
int w2 = pn->down->next->word_ref2;
Code__Activities__new(Kinds__unary_construction(CON_activity, K_nil), w1, w2);
}
#line 117 "inform7/Chapter 24/Activities.w"
int activity_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 121 "inform7/Chapter 24/Activities.w"
int activity_noted_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 142 "inform7/Chapter 24/Activities.w"
*X = FALSE;
Problems__sentence_problem(_P_(C24ActivityNoteUnknown),
"one of the notes about this activity makes no sense",
"and should be either 'documented at SYMBOL' or 'future action'.");
}
#line 124 "inform7/Chapter 24/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 126 "inform7/Chapter 24/Activities.w"
int activity_new_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 131 "inform7/Chapter 24/Activities.w"
#line 136 "inform7/Chapter 24/Activities.w"
int activity_name_construction_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 138 "inform7/Chapter 24/Activities.w"
#line 150 "inform7/Chapter 24/Activities.w"
activity *Code__Activities__new(kind *creation_kind, int w1, int w2) {
activity *av = CREATE(activity);
int wn;
int future_action_flag = FALSE;
specification *spec;
creation_kind = Kinds__unary_construction_material(creation_kind);
if ((Kinds__definite(creation_kind) == FALSE) &&
(Kinds__eq(creation_kind, K_nil) == FALSE)) {
LOG("I'm reading the kind as: $u\n", creation_kind);
Problems__sentence_problem(_P_(C24ActivityIndefinite),
"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.");
}
parse_nt_against_word_range(activity_sentence_subject_NTM, w1, w2, NULL, NULL);
GET_RW(activity_new_name_NTM, 1, w1, w2);
av->av_documentation_symbol_wn = ds_NTMV;
future_action_flag = future_NTMV;
if (any_NTMV) {
if (Kinds__eq(creation_kind, K_nil)) creation_kind = K_object;
} else {
if (Kinds__eq(creation_kind, K_nil) == FALSE) {
Problems__sentence_problem(_P_(C24ActivityMisnamed),
"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'.");
}
}
LOGIF(ACTION_CREATIONS, "Created activity: $W\n", w1, w2);
av->word_ref1 = w1; av->word_ref2 = w2;
Formats__Inform6__compose_identifier(av->av_I6_identifier, 'V', av->allocation_id, w1, w2);
av->activity_on_what_kind = creation_kind;
if (parse_nt_against_word_range(spec_value_NTM, w1, w2, NULL, NULL)) spec = most_recent_result_p;
else spec = Specifications__Unknown__new(w1, w2);
if (!(Specifications__is_UNKNOWN(spec)) && (!(Specifications__species_is(spec, PROPERTY_VALUE_SPC)))) {
LOG("$W means $S\n", w1, w2, spec);
Problems__sentence_problem(_P_(C24BadActivityName),
"this already has a meaning",
"and so cannot be the name of a newly created activity.");
} else {
Semantics__Nouns__ExcerptMeanings__register(ACTIVITY_MC, 0, w1, w2, STORE_POINTER_activity(av));
Semantics__Nouns__ExcerptMeanings__register_assemblage(ACTIVITY_MC, 0,
Text__Languages__merge(activity_name_construction_NTM, 0,
Text__Words__from_range(w1, w2)),
STORE_POINTER_activity(av));
}
wn = lexer_wordcount;
Text__feed_into_lexer("before", TRUE, NULL);
Text__splice_words(av->word_ref1, av->word_ref2);
av->before_rules =
Code__Rulebooks__new_automatic(wn, lexer_wordcount-1, av->activity_on_what_kind,
NO_OUTCOME, FALSE, future_action_flag, TRUE);
wn = lexer_wordcount;
Text__feed_into_lexer("for", TRUE, NULL);
Text__splice_words(av->word_ref1, av->word_ref2);
av->for_rules =
Code__Rulebooks__new_automatic(wn, lexer_wordcount-1, av->activity_on_what_kind,
SUCCESS_OUTCOME, FALSE, future_action_flag, TRUE);
wn = lexer_wordcount;
Text__feed_into_lexer("after", TRUE, NULL);
Text__splice_words(av->word_ref1, av->word_ref2);
av->after_rules =
Code__Rulebooks__new_automatic(wn, lexer_wordcount-1, av->activity_on_what_kind,
NO_OUTCOME, FALSE, future_action_flag, TRUE);
av->owned_by_av = Code__StackedVariables__Owners__new(10000+av->allocation_id);
Code__Rulebooks__make_stvs_accessible(av->before_rules, av->owned_by_av);
Code__Rulebooks__make_stvs_accessible(av->for_rules, av->owned_by_av);
Code__Rulebooks__make_stvs_accessible(av->after_rules, av->owned_by_av);
av->activity_indexed = FALSE;
av->cross_references = NULL;
return av;
}
specification *Code__Activities__to_specification(activity *av) {
kind *K = Kinds__unary_construction(CON_activity,
av->activity_on_what_kind);
specification *spec = Specifications__Values__new_actual_CONSTANT(K);
Specifications__set_structure_field(spec, STORE_POINTER_activity(av));
return spec;
}
activity *Code__Activities__from_specification(specification *spec) {
if (!(Specifications__Values__is_actual_CONSTANT_construction(spec, CON_activity))) {
LOG("Bad spec is: $S\n", spec);
internal_error("tried to find rulebook inside SP of wrong type");
}
activity *av = RETRIEVE_POINTER_activity(Specifications__get_structure_field(spec));
if (av == NULL) internal_error("found NULL rulebook within RULEBOOK spec");
return av;
}
#line 259 "inform7/Chapter 24/Activities.w"
int activity_variable_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 266 "inform7/Chapter 24/Activities.w"
*X = NOT_APPLICABLE;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C24ActivityVarAnd));
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 260 "inform7/Chapter 24/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 262 "inform7/Chapter 24/Activities.w"
#line 281 "inform7/Chapter 24/Activities.w"
void Code__Activities__add_variable(activity *av, parse_node *cnode) {
specification *spec;
int nw1 = -1, nw2 = -1, tw1 = -1, tw2 = -1;
if ((Parser__Nodes__type(cnode) != PROPERTYCALLED_NT) &&
(Parser__Nodes__type(cnode) != PROPER_NOUN_NT)) {
LOG("Tree: $T\n", cnode);
internal_error("ac_add_variable on a node of unknown type");
}
if (Parser__Nodes__type(cnode) == PROPER_NOUN_NT) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, nw1, nw2);
Problems__handmade_problem(_P_(C24ActivityVariableNameless));
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;
}
tw1 = cnode->down->word_ref1; tw2 = cnode->down->word_ref2;
nw1 = cnode->down->next->word_ref1; nw2 = cnode->down->next->word_ref2;
spec = NULL;
if (parse_nt_against_word_range(spec_type_expression_NTM, tw1, tw2, NULL, NULL)) spec = most_recent_result_p;
if (parse_nt_against_word_range(activity_variable_name_NTM, nw1, nw2, NULL, NULL)) {
if (most_recent_result == NOT_APPLICABLE) return;
}
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
if ((Specifications__Conditions__get_described_kind(spec)) &&
(Specifications__Conditions__number_of_adjectives_applied_to(spec) == 0)) {
spec = Specifications__Values__new_generic_CONSTANT(
Specifications__Conditions__get_described_kind(spec));
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, tw1, tw2);
Problems__handmade_problem(_P_(C24ActivityVarOverspecific));
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__Values__is_generic_CONSTANT(spec))) {
LOG("Offending SP: $X", spec);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, tw1, tw2);
Problems__handmade_problem(_P_(C24ActivityVarUnknownKOV));
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__eq(Specifications__get_kind(spec), K_value)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, tw1, tw2);
Problems__handmade_problem(_P_(C24ActivityVarValue));
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;
}
Code__StackedVariables__Owners__add(av->owned_by_av, nw1, nw2,
Specifications__get_kind(spec));
}
void Code__Activities__activity_var_creators_array(OUTPUT_STREAM) {
activity *av;
WRITE("Array activity_var_creators -->");
LOOP_OVER(av, activity) {
if (Code__StackedVariables__Owners__empty(av->owned_by_av)) WRITE(" 0");
else WRITE(" AVSTVC_%d", av->allocation_id);
}
WRITE(" 0;\n");
LOOP_OVER(av, activity) {
if (Code__StackedVariables__Owners__empty(av->owned_by_av) == FALSE)
Code__StackedVariables__Owners__compile_frame_creator(OUT, av->owned_by_av,
" AVSTVC_%d", av->allocation_id);
}
}
#line 383 "inform7/Chapter 24/Activities.w"
void Code__Activities__index_by_number(int id, int indent) {
activity *av;
LOOP_OVER(av, activity)
if (av->allocation_id == id) Code__Activities__index(av, indent);
}
void Code__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 (Code__Rulebooks__is_empty(av->before_rules, NULL) == FALSE) empty = FALSE;
if (Code__Rulebooks__is_empty(av->for_rules, NULL) == FALSE) empty = FALSE;
if (Code__Rulebooks__is_empty(av->after_rules, NULL) == FALSE) empty = FALSE;
if (av->cross_references) empty = FALSE;
if (av->av_documentation_symbol_wn >= 0)
doc_link = Text__word_raw_text(av->av_documentation_symbol_wn);
if (empty) text = "There are no rules before, for or after this activity.";
Code__Rulebooks__index_rules_box(NULL, av->word_ref1, av->word_ref2, doc_link,
NULL, av, text, indent, TRUE);
}
int Code__Activities__no_rules(activity *av) {
int t = 0;
t += Code__Rulebooks__no_rules(av->before_rules);
t += Code__Rulebooks__no_rules(av->for_rules);
t += Code__Rulebooks__no_rules(av->after_rules);
return t;
}
void Code__Activities__index_details(activity *av) {
int ignore_me = 0;
Code__Rulebooks__index(av->before_rules, "before", NULL, NULL, &ignore_me);
Code__Rulebooks__index(av->for_rules, "for", NULL, NULL, &ignore_me);
Code__Rulebooks__index(av->after_rules, "after", NULL, NULL, &ignore_me);
av_index_cross_references(av);
}
char *Code__Activities__identifier(activity *av) {
return av->av_I6_identifier;
}
int Code__Activities__Lists__count(activity_list *avl) {
int n = 0;
while (avl) {
n += 10;
if (avl->only_when) n += Specifications__Conditions__count(avl->only_when);
avl = avl->next;
}
return n;
}
#line 451 "inform7/Chapter 24/Activities.w"
int run_time_context_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
{
#line 488 "inform7/Chapter 24/Activities.w"
activity_list *al = *XP;
for (; al; al=al->next) {
al->ACL_parity = (al->ACL_parity)?FALSE:TRUE;
}
}
#line 452 "inform7/Chapter 24/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 454 "inform7/Chapter 24/Activities.w"
int activity_list_unnegated_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 496 "inform7/Chapter 24/Activities.w"
activity_list *al1 = RP[1], *al2 = RP[2];
al1->next = al2;
*XP = al1;
}
#line 457 "inform7/Chapter 24/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 459 "inform7/Chapter 24/Activities.w"
int activity_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 463 "inform7/Chapter 24/Activities.w"
int activity_list_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 503 "inform7/Chapter 24/Activities.w"
activity_list *al;
{
#line 540 "inform7/Chapter 24/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 504 "inform7/Chapter 24/Activities.w"
;
al->activity = RP[1];
}
#line 465 "inform7/Chapter 24/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 510 "inform7/Chapter 24/Activities.w"
activity *an = RP[1];
if (an->activity_on_what_kind == NULL) return FALSE;
if ((R[2]) &&
(Plugins__Actions__Patterns__validate_parameter(RP[2], an->activity_on_what_kind) == FALSE))
return FALSE;
activity_list *al;
{
#line 540 "inform7/Chapter 24/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 516 "inform7/Chapter 24/Activities.w"
;
al->activity = an;
al->acting_on = RP[2];
}
#line 466 "inform7/Chapter 24/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 510 "inform7/Chapter 24/Activities.w"
activity *an = RP[1];
if (an->activity_on_what_kind == NULL) return FALSE;
if ((R[2]) &&
(Plugins__Actions__Patterns__validate_parameter(RP[2], an->activity_on_what_kind) == FALSE))
return FALSE;
activity_list *al;
{
#line 540 "inform7/Chapter 24/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 516 "inform7/Chapter 24/Activities.w"
;
al->activity = an;
al->acting_on = RP[2];
}
#line 467 "inform7/Chapter 24/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 523 "inform7/Chapter 24/Activities.w"
specification *cond = Specifications__Commands__new();
activity_list *al;
{
#line 540 "inform7/Chapter 24/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 525 "inform7/Chapter 24/Activities.w"
;
al->only_when = cond;
}
#line 468 "inform7/Chapter 24/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 531 "inform7/Chapter 24/Activities.w"
specification *cond = RP[2];
if (Plugins__Actions__Patterns__validate_when(cond) == FALSE) return FALSE;
activity_list *al;
{
#line 540 "inform7/Chapter 24/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 534 "inform7/Chapter 24/Activities.w"
;
al->only_when = cond;
}
#line 469 "inform7/Chapter 24/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 470 "inform7/Chapter 24/Activities.w"
#line 480 "inform7/Chapter 24/Activities.w"
int activity_operand_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = FALSE; *XP = Specifications__Unknown__new(w1, w2);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE; *XP = Specifications__Unknown__new(w1, w2);;
#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 484 "inform7/Chapter 24/Activities.w"
#line 551 "inform7/Chapter 24/Activities.w"
int activity_name_NTMR(int w1, int w2, int *X, void **XP) {
#line 552 "inform7/Chapter 24/Activities.w"
meaning_list *ml = Parser__SP__parse_excerpt(ACTIVITY_MC, w1, w2);
if (ml) {
*XP = RETRIEVE_POINTER_activity(
Semantics__Nouns__ExcerptMeanings__data(
Parser__SP__MeaningLists__meaning(ml)));
return TRUE;
}
return FALSE;
}
#line 565 "inform7/Chapter 24/Activities.w"
int parsing_al_conditions = TRUE;
activity_list *Code__Activities__Lists__parse(int w1, int w2) {
return Code__Activities__Lists__parse_inner(w1, w2, TRUE);
}
activity_list *Code__Activities__Lists__parse_without_conditions(int w1, int w2) {
return Code__Activities__Lists__parse_inner(w1, w2, FALSE);
}
#line 578 "inform7/Chapter 24/Activities.w"
int if_parsing_al_conditions_NTMR(int w1, int w2, int *X, void **XP) {
#line 579 "inform7/Chapter 24/Activities.w"
if (parsing_al_conditions) return TRUE;
return FALSE;
}
#line 586 "inform7/Chapter 24/Activities.w"
activity_list *Code__Activities__Lists__parse_inner(int w1, int w2, int state) {
int save_pac = parsing_al_conditions;
parsing_al_conditions = state;
int rv = parse_nt_against_word_range(run_time_context_NTM, w1, w2, NULL, NULL);
parsing_al_conditions = save_pac;
if (rv) return most_recent_result_p;
return NULL;
}
void Code__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__species_is(al->acting_on, DESCRIPTION_SPC)) {
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__compile(OUT, al->acting_on);
WRITE("))");
}
}
else {
WRITE("(");
Specifications__compile(OUT, al->only_when);
WRITE(")");
}
al = al->next;
if (al != NULL) WRITE(" || ");
}
WRITE("))");
}
void Code__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 Code__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 Code__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 Code__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 Code__Activities__Activity_atb_rulebooks_array(OUTPUT_STREAM) {
activity *av; int i = 0;
WRITE("Array Activity_atb_rulebooks -> ");
LOOP_OVER(av, activity) {
WRITE("%d ", Code__Rulebooks__used_by_future_actions(av->before_rules));
i++;
}
if (i==0) WRITE("$ff ");
WRITE("$ff;\n");
}
void Code__Activities__Lists__annotate_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 av_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) && (ph->declaration_node->word_ref1 >= 0)) {
Formats__HTML__open_para(ifl, 2, "tight");
INDEX("NB: ");
Text__print_text_to_stream(ph->declaration_node->word_ref1,
ph->declaration_node->word_ref2, ifl);
Index__link(ph->declaration_node->word_ref1);
INDEX("</p>");
}
}
}
#line 61 "inform7/Chapter 25/Traverse for Grammar.w"
int base_problem_count = 0;
void Plugins__Parsing__traverse(void) {
parse_node *p;
TREE_LOOP(p)
if (Parser__Nodes__type(p) == SENTENCE_NT) {
if ((p->down)
&& (Parser__Nodes__type(p->down) == VERB_NT)
&& (Parser__Nodes__int_annotation(p->down, verb_id_ANNOT) == UNDERSTAND_VB)) {
int w1, w2, as1, as2;
w1 = p->down->next->word_ref1; w2 = p->down->next->word_ref2;
as1 = p->down->next->next->word_ref1; as2 = p->down->next->next->word_ref2;
base_problem_count = problem_count;
understand_sentence(w1, w2, as1, as2);
Parser__SP__MeaningLists__finish_this_session();
}
}
}
#line 90 "inform7/Chapter 25/Traverse for Grammar.w"
void Plugins__Parsing__compile_understanding(OUTPUT_STREAM, int w1, int w2, int table_entry) {
if (parse_nt_against_word_range(nominative_pronoun_NTM, w1, w2, NULL, NULL)) WRITE("0");
else {
cached_understanding *cu;
LOOP_OVER(cu, cached_understanding)
if ((cu->word_ref1 == w1) && (cu->word_ref2 == w2)) {
WRITE("Consult_Grammar_%d", cu->consult_grammar_no);
return;
}
base_problem_count = problem_count;
Plugins__Parsing__Tokens__General__prepare_consultation_gv();
if (table_entry) {
int k;
for (k = w1; k <= w2; k++) {
if (parse_nt_against_word_range(quoted_text_NTM, k, k, NULL, NULL)) {
understand_block(k, k, NULL, -1, -1, TRUE);
}
}
} else {
understand_block(w1, w2, NULL, -1, -1, FALSE);
}
int G = Plugins__Parsing__Tokens__General__print_consultation_gv_name(OUT);
if (G >= 0) {
cu = CREATE(cached_understanding);
cu->word_ref1 = w1; cu->word_ref2 = w2; cu->consult_grammar_no = G;
}
}
}
#line 138 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 148 "inform7/Chapter 25/Traverse for Grammar.w"
*X = NO_UNDERSTAND_FORM;
Problems__sentence_problem(_P_(C25OldVerbUsage),
"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 142 "inform7/Chapter 25/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 144 "inform7/Chapter 25/Traverse for Grammar.w"
#line 160 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_regular_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 202 "inform7/Chapter 25/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 162 "inform7/Chapter 25/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 164 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_regular_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 168 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_regular_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 214 "inform7/Chapter 25/Traverse for Grammar.w"
*XP = NULL;
if (!preform_lookahead_mode) {
understanding_item *ui = CREATE(understanding_item);
ui->quoted_text_w1 = w1;
ui->quoted_text_w2 = w2;
ui->quoted_property = NULL;
ui->next = NULL;
*XP = ui;
}
}
#line 170 "inform7/Chapter 25/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 171 "inform7/Chapter 25/Traverse for Grammar.w"
#line 176 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_property_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 202 "inform7/Chapter 25/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 178 "inform7/Chapter 25/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 180 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_property_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 184 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_property_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 227 "inform7/Chapter 25/Traverse for Grammar.w"
*XP = NULL;
if (!preform_lookahead_mode) {
understanding_item *ui = CREATE(understanding_item);
ui->quoted_text_w1 = -1;
ui->quoted_text_w2 = -1;
ui->quoted_property = RP[1];
ui->next = NULL;
*XP = ui;
}
}
#line 186 "inform7/Chapter 25/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 192 "inform7/Chapter 25/Traverse for Grammar.w"
if (!preform_lookahead_mode)
Problems__sentence_problem(_P_(C25UnknownUnderstandProperty),
"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 187 "inform7/Chapter 25/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 188 "inform7/Chapter 25/Traverse for Grammar.w"
#line 240 "inform7/Chapter 25/Traverse for Grammar.w"
understanding_reference ur_being_parsed;
#line 251 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 254 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_sentence_object_uncond_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 270 "inform7/Chapter 25/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 257 "inform7/Chapter 25/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 259 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_sentence_object_tail_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 263 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_sentence_entry_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; if (!preform_lookahead_mode)
{
#line 282 "inform7/Chapter 25/Traverse for Grammar.w"
if (R[1] == -1) {
*XP = NULL;
} else {
understanding_reference *ur = CREATE(understanding_reference);
*ur = ur_being_parsed;
*XP = ur;
}
}
#line 265 "inform7/Chapter 25/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 266 "inform7/Chapter 25/Traverse for Grammar.w"
#line 293 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_as_this_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0;
{
#line 313 "inform7/Chapter 25/Traverse for Grammar.w"
ur_being_parsed.word_ref1 = w1; ur_being_parsed.word_ref2 = w2;
ur_being_parsed.mword = -1;
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 294 "inform7/Chapter 25/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;;
#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.mword = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 325 "inform7/Chapter 25/Traverse for Grammar.w"
*X = -1;
Problems__sentence_problem(_P_(C25TextlessMistake),
"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 297 "inform7/Chapter 25/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 303 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_ref_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 335 "inform7/Chapter 25/Traverse for Grammar.w"
*X = -1;
LOG("Offending pseudo-meaning is: $W\n", w1, w2);
Problems__sentence_problem(_P_(C25UnderstandVariable),
"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 307 "inform7/Chapter 25/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 349 "inform7/Chapter 25/Traverse for Grammar.w"
*X = -1;
LOG("Offending pseudo-meaning is: $W\n", w1, w2);
{
#line 356 "inform7/Chapter 25/Traverse for Grammar.w"
Problems__sentence_problem(_P_(C25UnderstandVague),
"'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 351 "inform7/Chapter 25/Traverse for Grammar.w"
;
}
#line 308 "inform7/Chapter 25/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 309 "inform7/Chapter 25/Traverse for Grammar.w"
#line 376 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_command_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 385 "inform7/Chapter 25/Traverse for Grammar.w"
*X = -1;
Problems__sentence_problem(_P_(C25UnderstandCommandWhen),
"'understand the command ... as ...' is not allowed to have a "
"'... when ...' clause",
"for the moment at any rate.");
}
#line 377 "inform7/Chapter 25/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 = w1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 394 "inform7/Chapter 25/Traverse for Grammar.w"
*X = -1;
{
#line 572 "inform7/Chapter 25/Traverse for Grammar.w"
Problems__sentence_problem(_P_(C25NotOldCommand),
"'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 395 "inform7/Chapter 25/Traverse for Grammar.w"
;
}
#line 380 "inform7/Chapter 25/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 381 "inform7/Chapter 25/Traverse for Grammar.w"
#line 405 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_property_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 408 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_property_sentence_object_unconditional_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 429 "inform7/Chapter 25/Traverse for Grammar.w"
*X = 0;
Problems__sentence_problem(_P_(C25BadUnderstandProperty),
"'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 412 "inform7/Chapter 25/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 413 "inform7/Chapter 25/Traverse for Grammar.w"
int understand_property_reference_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 422 "inform7/Chapter 25/Traverse for Grammar.w"
kind *K = RP[1];
if (Kinds__lt(K, K_object)) *XP = Kinds__as_subject(K);
else return FALSE;
}
#line 415 "inform7/Chapter 25/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = Data__Instances__as_subject(RP[1]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 439 "inform7/Chapter 25/Traverse for Grammar.w"
*XP = NULL;
Problems__sentence_problem(_P_(C25BadUnderstandPropertyAs),
"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 417 "inform7/Chapter 25/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 418 "inform7/Chapter 25/Traverse for Grammar.w"
#line 450 "inform7/Chapter 25/Traverse for Grammar.w"
void understand_sentence(int w1, int w2, int as1, int as2) {
LOGIF(GRAMMAR, "Parsing understand <$W> as <$W>\n", w1, w2, as1, as2);
if (problem_count > base_problem_count) return;
parse_nt_against_word_range(understand_sentence_subject_NTM, w1, w2, 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 468 "inform7/Chapter 25/Traverse for Grammar.w"
parse_nt_against_word_range(understand_command_sentence_object_NTM, as1, as2, NULL, NULL);
if (problem_count > base_problem_count) return;
int wn = most_recent_result;
for (; ui_list; ui_list = ui_list->next) {
if (problem_count > base_problem_count) break;
int x1 = ui_list->quoted_text_w1, x2 = ui_list->quoted_text_w2;
understand_the_command(x1, x2, wn);
}
}
#line 458 "inform7/Chapter 25/Traverse for Grammar.w"
; break;
case PROPERTY_UNDERSTAND_FORM:
{
#line 480 "inform7/Chapter 25/Traverse for Grammar.w"
parse_nt_against_word_range(understand_property_sentence_object_NTM, as1, as2, NULL, NULL);
if (problem_count > base_problem_count) return;
int uw1 = -1, uw2 = -1;
inference_subject *subj = most_recent_result_p;
if (most_recent_result == 2) { GET_RW(understand_property_sentence_object_NTM, 1, uw1, uw2); }
for (; ui_list; ui_list = ui_list->next) {
if (problem_count > base_problem_count) break;
understand_property_block(ui_list->quoted_property, level_NTMV, subj, uw1, uw2);
}
}
#line 459 "inform7/Chapter 25/Traverse for Grammar.w"
; break;
case GRAMMAR_UNDERSTAND_FORM: /* and */
case NOTHING_UNDERSTAND_FORM:
{
#line 493 "inform7/Chapter 25/Traverse for Grammar.w"
parse_nt_against_word_range(understand_sentence_object_NTM, as1, as2, NULL, NULL);
if (problem_count > base_problem_count) return;
understanding_reference *ur_list_from = most_recent_result_p;
int uw1 = -1, uw2 = -1;
if (most_recent_result == 2) { GET_RW(understand_sentence_object_NTM, 1, uw1, uw2); }
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;
understand_nothing(ur_list, uw1, uw2);
}
} else {
for (; ui_list; ui_list = ui_list->next) {
int x1 = ui_list->quoted_text_w1, x2 = ui_list->quoted_text_w2;
understanding_reference *ur_list;
for (ur_list = ur_list_from; ur_list; ur_list = ur_list->next) {
if (problem_count > base_problem_count) break;
understand_block(x1, x2, ur_list, uw1, uw2, FALSE);
}
}
}
}
#line 461 "inform7/Chapter 25/Traverse for Grammar.w"
; break;
}
}
#line 528 "inform7/Chapter 25/Traverse for Grammar.w"
void understand_the_command(int w1, int w2, int wn) {
Text__dequote_word(w2);
char *p = Text__word_text(w2);
for (int i=0; p[i]; i++)
if (p[i] == ' ') {
Problems__sentence_problem(_P_(C25SpacyCommand),
"'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 = Plugins__Parsing__Verbs__find_command(w2);
if (wn == 0) {
if (gv) Plugins__Parsing__Verbs__remove_command(gv, w2);
} else {
if (gv) {
if (Plugins__Parsing__Verbs__is_empty(gv)) {
DESTROY(gv, grammar_verb);
gv = NULL;
} else {
Problems__sentence_problem(_P_(C25NotNewCommand),
"'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(wn);
gv = Plugins__Parsing__Verbs__find_command(wn);
if (gv == NULL) {
{
#line 572 "inform7/Chapter 25/Traverse for Grammar.w"
Problems__sentence_problem(_P_(C25NotOldCommand),
"'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 562 "inform7/Chapter 25/Traverse for Grammar.w"
;
} else {
Plugins__Parsing__Verbs__add_command(gv, w2);
}
}
}
#line 587 "inform7/Chapter 25/Traverse for Grammar.w"
void understand_property_block(property *pr, int level, inference_subject *subj, int when1, int when2) {
if ((Properties__is_either_or(pr) == FALSE) &&
(Kinds__get_recognition_only_GPR(Properties__Valued__kind(pr)) == NULL) &&
((Kinds__le(Properties__Valued__kind(pr), K_object)) ||
(Kinds__request_I6_GPR(Properties__Valued__kind(pr)) == FALSE))) {
Problems__sentence_problem(_P_(C25BadReferringProperty),
"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 (Plugins__Parsing__Visibility__seek(pr, subj, level, when1, when2) == FALSE) {
Problems__sentence_problem(_P_(C25UnknownUnpermittedProperty),
"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 614 "inform7/Chapter 25/Traverse for Grammar.w"
void understand_nothing(understanding_reference *ur, int when1, int when2) {
if ((ur == NULL) || (ur->gv_result != GV_IS_OBJECT) || (ur->an_reference == NULL)) {
Problems__sentence_problem(_P_(C25UnderstandNothingNonAction),
"'Understand nothing as ...' must be followed by an action",
"such as 'Understand nothing as taking.'");
} else if (when1 >= 0) {
Problems__sentence_problem(_P_(C25UnderstandNothingWhen),
"'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);
Plugins__Actions__remove_gl(an);
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb) Plugins__Parsing__Verbs__remove_action(gv, an);
}
}
#line 635 "inform7/Chapter 25/Traverse for Grammar.w"
void understand_block(int w1, int w2, understanding_reference *ur, int when1, int when2,
int table_entry) {
int x1, x2, gv_is = GV_IS_COMMAND,
reversed = FALSE, file_under_vn = -1, mistake_text_at = 0, pluralised = FALSE;
kind *K = NULL;
action_name *an = NULL;
grammar_line *gl = NULL;
parse_node *to_pn = NULL;
inference_subject *subj = NULL;
property *gv_prn = NULL;
specification *gl_value = NULL;
if (problem_count > base_problem_count) return;
if (parse_nt_against_word_range(quoted_text_NTM, w1, w2, NULL, NULL) == FALSE) {
if (table_entry)
Problems__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
Problems__sentence_problem(_P_(C25NontextualUnderstand),
"'understand' should be followed by a textual description",
"as in 'understand \"take [something]\" as taking the noun'.");
return;
}
if (Text__well_formed_text_routine(Text__word_text(w1)) == FALSE) {
Problems__sentence_problem(_P_(C25UnderstandMismatch),
"'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;
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;
gv_is = ur->gv_result;
if (gv_is == GV_IS_OBJECT) {
gv_is = GV_IS_COMMAND;
if (an == NULL) {
instance *target;
specification *spec = ur->spec_reference;
target = Specifications__object_exactly_described_if_any(spec);
if (target) {
subj = Data__Instances__as_subject(target);
gv_is = GV_IS_OBJECT;
if (Specifications__Conditions__is_qualified_DESCRIPTION(spec)) {
LOG("Offending description: $X", spec);
Problems__sentence_problem(_P_(C25UnderstandAsQualified),
"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: $X", spec);
if (Specifications__Values__is_generic_CONSTANT(spec)) goto ImpreciseProblemMessage;
if (Specifications__is_phrasal(spec)) goto ImpreciseProblemMessage;
if (Specifications__Values__is_nothing_object_constant(spec)) goto ImpreciseProblemMessage;
if (Specifications__family_is(spec, VALUE_FMY)) {
K = Specifications__get_kind(spec);
if (Kinds__request_I6_GPR(K)) {
gl_value = spec;
gv_is = GV_IS_VALUE;
} else {
if (Kinds__get_construct(K) == CON_activity)
Problems__sentence_problem(_P_(C25UnderstandAsActivity),
"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__sentence_problem(_P_(C25UnderstandAsBadValue),
"'understand ... as ...' gives text "
"meaning a value whose kind is not allowed",
"and should be a value such as 100.");
return;
}
} else if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
if ((Specifications__Conditions__get_described_instance(spec) == NULL) &&
(Kinds__lt(Specifications__Conditions__get_described_kind(spec),
K_object) == FALSE)
&& (Specifications__Conditions__number_of_adjectives_applied_to(spec) == 1)
&& (Specifications__Conditions__adjective_used_positively(Specifications__Conditions__first_adjective_list_entry(spec)))) {
adjectival_phrase *aph =
Specifications__Conditions__get_adjective_from_list_entry(Specifications__Conditions__first_adjective_list_entry(spec));
instance *q = Semantics__Adjectives__Phrases__has_ENUMERATIVE_meaning(aph);
if (q) {
spec = Specifications__Values__new_named_CONSTANT(q);
goto RetryValue;
}
property *prn = Semantics__Adjectives__Phrases__has_EORP_meaning(aph);
if (prn) {
gv_is = GV_IS_PROPERTY_NAME;
gv_prn = prn;
LOGIF(GRAMMAR_CONSTRUCTION, "Grammar confirmed for property $Y\n", gv_prn);
}
}
kind *K = Specifications__Conditions__get_described_kind(spec);
if ((K) && (Kinds__lt(K, K_object))) {
subj = Kinds__as_subject(K);
gv_is = GV_IS_OBJECT;
}
if ((Specifications__Conditions__is_qualified_DESCRIPTION(spec)) && (gv_prn == NULL)) {
LOG("Offending description: $X", spec);
Problems__sentence_problem(_P_(C25ComplexUnderstand),
"I cannot understand text as having so complicated "
"a meaning",
"only a specific thing, a specific value or a kind. "
"So 'Understand \"darce\" as Mr Darcy' is allowed, "
"but 'Understand \"bucket\" as an open container' "
"is not, because it is too general a description.");
return;
}
} else {
ImpreciseProblemMessage:
LOG("Offending pseudo-meaning is: $X", spec);
{
#line 356 "inform7/Chapter 25/Traverse for Grammar.w"
Problems__sentence_problem(_P_(C25UnderstandVague),
"'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 766 "inform7/Chapter 25/Traverse for Grammar.w"
;
return;
}
}
}
}
}
if ((pluralised) && (gv_is != GV_IS_OBJECT)) {
Problems__sentence_problem(_P_(C25UnderstandPluralValue),
"'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 = Text__word_text(w1);
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__sentence_problem(_P_(C25LiteralPunctuation),
"'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;
}
Text__feed_into_lexer(Text__word_text(w1), TRUE, GRAMMAR_PUNCTUATION_MARKS);
x1 = lexer_feed_w1; x2 = lexer_feed_w2;
to_pn = Parser__Sentences__NPs__new_raw(w1, w2);
Plugins__Parsing__Tokens__break_into_tokens(to_pn, x1, x2);
if (to_pn->down == NULL) {
Problems__sentence_problem(_P_(C25UnderstandEmptyText),
"'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) {
int i;
LOGIF(GRAMMAR_CONSTRUCTION, "Command grammar: $T\n", to_pn);
for (i=x1; i<x2; i++) {
if ((compare_word(i, COMMA_V)) && (compare_word(i+1, COMMA_V))) {
Problems__sentence_problem(_P_(C25UnderstandCommaCommand),
"'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 (Plugins__Parsing__Tokens__is_literal(to_pn->down) == FALSE)
file_under_vn = -1; /* this will go into the no verb verb */
else file_under_vn = to_pn->down->word_ref1;
}
LOGIF(GRAMMAR, "GV is %d, an is $l, file under is $W\n", gv_is, an,
file_under_vn, file_under_vn);
if (gv_is != GV_IS_COMMAND) gl = Plugins__Parsing__Lines__new(w1, NULL, to_pn, reversed, pluralised);
else gl = Plugins__Parsing__Lines__new(w1, an, to_pn, reversed, pluralised);
if (mistake_text_at != 0) Plugins__Parsing__Lines__set_mistake(gl, mistake_text_at);
if (when1 >= 0) {
Plugins__Parsing__Lines__set_understand_when(gl, when1, when2);
if (gv_is == GV_IS_CONSULT) {
Problems__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:
Text__feed_into_lexer(Text__word_text(ur->word_ref1), TRUE, GRAMMAR_PUNCTUATION_MARKS);
x1 = lexer_feed_w1; x2 = lexer_feed_w2;
LOGIF(GRAMMAR_CONSTRUCTION, "GV_IS_TOKEN as words: $W\n", x1, x2);
if (valid_new_token_name(x1, x2) == FALSE) {
Problems__sentence_problem(_P_(C25UnderstandAsCompoundText),
"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.");
}
Plugins__Parsing__Verbs__add_line(Plugins__Parsing__Verbs__named_token_new(x1+2, x2-2), gl);
break;
case GV_IS_COMMAND:
Plugins__Parsing__Verbs__add_line(Plugins__Parsing__Verbs__find_or_create_command(file_under_vn), gl);
break;
case GV_IS_OBJECT:
Plugins__Parsing__Verbs__add_line(Plugins__Parsing__Verbs__for_subject(subj), gl);
break;
case GV_IS_VALUE:
Plugins__Parsing__Lines__set_single_type(gl, gl_value);
Plugins__Parsing__Verbs__add_line(Plugins__Parsing__Verbs__for_kind(K), gl);
break;
case GV_IS_PROPERTY_NAME:
Plugins__Parsing__Verbs__add_line(Plugins__Parsing__Verbs__for_prn(gv_prn), gl);
break;
case GV_IS_CONSULT:
Plugins__Parsing__Lines__set_single_type(gl, gl_value);
Plugins__Parsing__Verbs__add_line(
Plugins__Parsing__Tokens__General__get_consultation_gv(), gl);
break;
}
}
int valid_new_token_name(int w1, int w2) {
int i, cc=0;
for (i=w1; i<=w2; i++)
if (compare_word(i, COMMA_V)) cc++;
Text__dequote_word(w1);
if (*(Text__word_text(w1)) != 0) return FALSE;
Text__dequote_word(w2);
if (*(Text__word_text(w2)) != 0) return FALSE;
if (cc != 2) return FALSE;
return TRUE;
}
#line 54 "inform7/Chapter 25/Grammar Properties.w"
parsing_data *parsing_plugin_new_data(inference_subject *subj) {
parsing_data *pd = CREATE(parsing_data);
pd->understand_as_this_object = NULL;
return pd;
}
parsing_pp_data *parsing_plugin_new_pp_data(property_permission *pp) {
parsing_pp_data *pd = CREATE(parsing_pp_data);
pd->visibility_level_in_parser = 0;
pd->visibility_condition_w1 = -1;
pd->visibility_condition_w2 = -1;
pd->visibility_sentence = NULL;
return pd;
}
#line 72 "inform7/Chapter 25/Grammar Properties.w"
void Plugins__Parsing__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_VARIABLE_NOTIFY, parsing_new_variable_notify);
PLUGIN_REGISTER(PLUGIN_NEW_SUBJECT_NOTIFY, parsing_new_subject_notify);
PLUGIN_REGISTER(PLUGIN_NEW_PERMISSION_NOTIFY, parsing_new_permission_notify);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, parsing_complete_model);
PLUGIN_REGISTER(PLUGIN_ESTIMATE_PROPERTY_USAGE, parsing_estimate_property_usage);
}
int parsing_new_subject_notify(inference_subject *subj) {
CREATE_PF_DATA(parsing, subj);
return FALSE;
}
int parsing_new_permission_notify(property_permission *new_pp) {
CREATE_PLUGIN_PP_DATA(parsing, new_pp);
return FALSE;
}
#line 97 "inform7/Chapter 25/Grammar Properties.w"
int notable_parsing_variables_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 106 "inform7/Chapter 25/Grammar Properties.w"
#line 110 "inform7/Chapter 25/Grammar Properties.w"
int parsing_new_variable_notify(nonlocal_variable *var) {
int w1 = var->word_ref1, w2 = var->word_ref2;
if (parse_nt_against_word_range(notable_parsing_variables_NTM, w1, w2, NULL, NULL)) {
switch (most_recent_result) {
case 0:
if (kind_understood_NTMV == Data__NonlocalVariables__kind(var))
Data__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;
Data__NonlocalVariables__make_initalisable(var); break;
case 7: parameter_object_VAR = var; break;
}
}
return FALSE;
}
#line 135 "inform7/Chapter 25/Grammar Properties.w"
int parsing_estimate_property_usage(kind *k, int *words_used) {
int w1, w2;
Kinds__get_name(k, &w1, &w2, FALSE);
if (w1 >= 0) *words_used += (w2-w1+1);
int pw1, pw2;
Kinds__get_name(k, &pw1, &pw2, TRUE);
if (pw1 >= 0) *words_used += (pw2-pw1+1);
return FALSE;
}
#line 149 "inform7/Chapter 25/Grammar Properties.w"
int 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 = Data__Instances__as_subject(I);
{
#line 194 "inform7/Chapter 25/Grammar Properties.w"
if (Plugins__Naming__object_is_privately_named(I) == FALSE) {
kind *K = Data__Instances__kind(I);
int w1, w2, j, from_kind = FALSE;
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");
int pw1, pw2;
Data__Instances__get_name_in_play(I, &w1, &w2, FALSE);
if (w1 < 0) Kinds__get_name_in_play(K, &w1, &w2, FALSE);
Data__Instances__get_name_in_play(I, &pw1, &pw2, TRUE);
if (pw1 < 0) {
from_kind = TRUE; Kinds__get_name_in_play(K, &pw1, &pw2, TRUE);
}
for (j=w1; j<=w2; j++) {
vocabulary_entry *ve = Text__word(j);
ve = Text__Languages__replace_word(ve,
possessive_second_person_NTM,
possessive_first_person_NTM);
char *p = Text__Vocabulary__get_exemplar(ve, FALSE);
Formats__Inform6__compile_dictionary_word(name_text, p, FALSE);
STREAM_WRITE(name_text, " ");
}
if (from_kind) /* see test case C9PluralsFromKind */
for (j=pw1; j<=pw2; j++) {
int k, additional = TRUE;
for (k=w1; k<=w2; k++)
if (compare_word(j, Text__word(k))) additional = FALSE;
if (additional) Formats__Inform6__compile_dictionary_word(name_text, Text__word_text(j), TRUE);
STREAM_WRITE(name_text, " ");
}
if (PF_I(parsing, I)->understand_as_this_object)
Plugins__Parsing__Verbs__take_out_one_word_grammar(name_text,
PF_I(parsing, I)->understand_as_this_object);
inference_subject *infs;
for (infs = Kinds__as_subject(Data__Instances__kind(I));
infs; infs = World__Subjects__narrowest_broader_subject(infs)) {
if (PF_S(parsing, infs)) {
if (PF_S(parsing, infs)->understand_as_this_object)
Plugins__Parsing__Verbs__take_out_one_word_grammar(name_text,
PF_S(parsing, infs)->understand_as_this_object);
}
}
Properties__Valued__assert(P_name, Data__Instances__as_subject(I),
Specifications__Values__faux_text_literal_from_stream(name_text), CERTAIN_CE);
}
}
#line 158 "inform7/Chapter 25/Grammar Properties.w"
;
{
#line 248 "inform7/Chapter 25/Grammar Properties.w"
STREAM *S = Plugins__Parsing__Tokens__General__compile_parse_name_property(subj);
if (S)
Properties__Valued__assert(P_parse_name, subj,
Specifications__Values__faux_text_literal_from_stream(S), CERTAIN_CE);
}
#line 159 "inform7/Chapter 25/Grammar Properties.w"
;
{
#line 262 "inform7/Chapter 25/Grammar Properties.w"
if (World__Subjects__is_within(subj, Kinds__as_subject(K_room)) == FALSE) {
STREAM *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for name text");
Plugins__Actions__compile_action_bitmap_property(PROP);
Properties__Valued__assert(P_action_bitmap, subj,
Specifications__Values__faux_text_literal_from_stream(PROP), CERTAIN_CE);
}
}
#line 160 "inform7/Chapter 25/Grammar Properties.w"
;
}
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__lt(K, K_object)) {
inference_subject *subj = Kinds__as_subject(K);
{
#line 248 "inform7/Chapter 25/Grammar Properties.w"
STREAM *S = Plugins__Parsing__Tokens__General__compile_parse_name_property(subj);
if (S)
Properties__Valued__assert(P_parse_name, subj,
Specifications__Values__faux_text_literal_from_stream(S), CERTAIN_CE);
}
#line 167 "inform7/Chapter 25/Grammar Properties.w"
;
}
inference_subject *subj = Kinds__as_subject(K_thing);
{
#line 262 "inform7/Chapter 25/Grammar Properties.w"
if (World__Subjects__is_within(subj, Kinds__as_subject(K_room)) == FALSE) {
STREAM *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for name text");
Plugins__Actions__compile_action_bitmap_property(PROP);
Properties__Valued__assert(P_action_bitmap, subj,
Specifications__Values__faux_text_literal_from_stream(PROP), CERTAIN_CE);
}
}
#line 171 "inform7/Chapter 25/Grammar Properties.w"
;
}
return FALSE;
}
#line 282 "inform7/Chapter 25/Grammar Properties.w"
int Plugins__Parsing__Visibility__seek(property *pr, inference_subject *subj,
int level, int when1, int when2) {
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_w1 = when1;
PLUGIN_PP(parsing, pp)->visibility_condition_w2 = when2;
return TRUE;
}
return FALSE;
}
int Plugins__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 Plugins__Parsing__Visibility__get_level(property_permission *pp) {
return PLUGIN_PP(parsing, pp)->visibility_level_in_parser;
}
specification *Plugins__Parsing__Visibility__get_condition(property_permission *pp) {
specification *spec;
int c1 = PLUGIN_PP(parsing, pp)->visibility_condition_w1,
c2 = PLUGIN_PP(parsing, pp)->visibility_condition_w2;
if (c1 == -1) return NULL;
spec = NULL;
if (parse_nt_against_word_range(spec_condition_NTM, c1, c2, NULL, NULL)) spec = most_recent_result_p;
else spec = Specifications__Unknown__new(c1, c2);
if (Plugins__Actions__Patterns__validate_when(spec) == FALSE) {
LOG("$X", spec);
current_sentence = PLUGIN_PP(parsing, pp)->visibility_sentence;
Problems__sentence_problem(_P_(C25BadVisibilityWhen),
"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_w1 = -1;
PLUGIN_PP(parsing, pp)->visibility_condition_w2 = -1;
return NULL;
}
return spec;
}
void 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_w1,
PLUGIN_PP(parsing, pp)->visibility_condition_w2);
}
if (World__Subjects__narrowest_broader_subject(infs))
log_parsing_visibility(World__Subjects__narrowest_broader_subject(infs));
}
#line 354 "inform7/Chapter 25/Grammar Properties.w"
int Plugins__Parsing__is_an_action_variable(specification *spec) {
nonlocal_variable *nlv;
if (spec == NULL) return FALSE;
if (Specifications__Storage__get_storage_form(spec) != NONLOCAL_VARIABLE_SPC) return FALSE;
nlv = RETRIEVE_FROM_SPEC(spec, nonlocal_variable);
if (nlv == I6_noun_VAR) return TRUE;
if (nlv == I6_second_VAR) return TRUE;
if (nlv == I6_actor_VAR) return TRUE;
return FALSE;
}
#line 89 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb *gv_new(int gv_is) {
grammar_verb *gv;
gv = CREATE(grammar_verb);
gv->command_wn = -1;
gv->first_line = NULL;
gv->gv_type = Plugins__Parsing__Tokens__Types__new(FALSE);
gv->gv_is = gv_is;
gv->word_ref1 = -1; gv->word_ref2 = -1;
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 Plugins__Parsing__Verbs__log(grammar_verb *gv) {
LOG("<GV%d:", gv->allocation_id);
switch(gv->gv_is) {
case GV_IS_COMMAND:
if (gv->command_wn == -1) LOG("command=no-verb verb");
else LOG("command=$W", gv->command_wn, gv->command_wn);
break;
case GV_IS_TOKEN: LOG("token=$W", gv->word_ref1, gv->word_ref2); 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 25/Grammar Verbs.w"
int Plugins__Parsing__Verbs__get_verb_wn(grammar_verb *gv) {
return gv->command_wn;
}
int gv_is_genuinely_verbal(grammar_verb *gv) {
if ((gv->gv_is == GV_IS_COMMAND) && (gv->command_wn != -1))
return TRUE;
return FALSE;
}
#line 166 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb *Plugins__Parsing__Verbs__find_or_create_command(int vw) {
grammar_verb *gv = Plugins__Parsing__Verbs__find_command(vw);
if (gv) return gv;
gv = gv_new(GV_IS_COMMAND);
gv->command_wn = vw;
if (vw == -1) no_verb_verb_defined = TRUE;
else {
LOGIF(GRAMMAR_CONSTRUCTION, "GV%d has verb %d = <%s>\n",
gv->allocation_id, vw, Text__word_text(vw));
}
return gv;
}
#line 186 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb *Plugins__Parsing__Verbs__find_command(int vw) {
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_COMMAND) {
int i;
if (vw == -1) {
if (gv->command_wn == -1) return gv;
} else {
if ((gv->command_wn >= 0) && (compare_words(vw, gv->command_wn)))
return gv;
for (i=0; i<gv->no_aliased_commands; i++)
if ((gv->aliased_command_wn[i] >= 0) &&
(compare_words(vw, gv->aliased_command_wn[i])))
return gv;
}
}
return NULL;
}
#line 216 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__add_command(grammar_verb *gv, int wn) {
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__sentence_problem(_P_(C25TooManyAliases),
"this 'understand the command ... as ...' makes too many aliases "
"for the same command",
"exceeding the limit of 32.");
return;
}
gv->aliased_command_wn[gv->no_aliased_commands++] = wn;
LOGIF(GRAMMAR, "Adding alias '%s' (%d) to G%d '%s' (%d)\n",
Text__word_text(wn), wn, gv->allocation_id, Text__word_text(gv->command_wn), gv->command_wn);
}
void Plugins__Parsing__Verbs__remove_command(grammar_verb *gv, int wn) {
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 '%s' from grammar\n", Text__word_text(wn));
if (gv == NULL) return;
if (compare_words(gv->command_wn, wn)) {
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_wn = gv->aliased_command_wn[--(gv->no_aliased_commands)];
LOGIF(GRAMMAR, "Which had aliases: making new head-verb '%s'\n",
Text__word_text(gv->command_wn));
}
} else {
LOGIF(GRAMMAR, "Detached verb is one of the aliases\n");
int i, j;
for (i=0; i<gv->no_aliased_commands; i++) {
if (compare_words(gv->aliased_command_wn[i], wn)) {
for (j=i; j<gv->no_aliased_commands-1; j++)
gv->aliased_command_wn[j] = gv->aliased_command_wn[j+1];
gv->no_aliased_commands--;
break;
}
}
}
}
void Plugins__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", Text__word_text(gv->aliased_command_wn[i]));
}
void Plugins__Parsing__Verbs__remove_action(grammar_verb *gv, action_name *an) {
if (gv->gv_is != GV_IS_COMMAND) return;
gv->first_line = Plugins__Parsing__Lines__list_remove(gv->first_line, an);
}
#line 279 "inform7/Chapter 25/Grammar Verbs.w"
void 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 (gv->command_wn == -1)
WRITE("Verb 'no.verb'");
else {
int i;
WRITE("Verb ");
if (command_verb_reserved(Text__word_text(gv->command_wn))) {
current_sentence = gv->where_gv_created;
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, Text__word_text(gv->command_wn));
Problems__handmade_problem(_P_(C25ReservedVerb));
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();
}
Formats__Inform6__compile_dictionary_word(OUT, Text__word_text(gv->command_wn), FALSE);
for (i=0; i<gv->no_aliased_commands; i++) {
WRITE(" ");
Formats__Inform6__compile_dictionary_word(OUT, Text__word_text(gv->aliased_command_wn[i]), FALSE);
}
}
WRITE("\n");
}
#line 314 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__reserve(char *verb_name) {
reserved_command_verb *rcv = CREATE(reserved_command_verb);
normalise_cv_to(verb_name, rcv->reserved_text);
Plugins__Actions__Index__test_verb(rcv->reserved_text);
}
int command_verb_reserved(char *verb_tried) {
reserved_command_verb *rcv;
char normalised_vt[32];
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 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 347 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__make_command_index_entries(grammar_verb *gv) {
if ((gv->gv_is == GV_IS_COMMAND) && (gv->first_line)) {
int i;
if (gv->command_wn == -1)
Plugins__Actions__Index__vie_new_from("0", gv, NORMAL_COMMAND);
else
Plugins__Actions__Index__vie_new_from(Text__word_text(gv->command_wn), gv, NORMAL_COMMAND);
for (i=0; i<gv->no_aliased_commands; i++)
Plugins__Actions__Index__vie_new_from(Text__word_text(gv->aliased_command_wn[i]), gv, ALIAS_COMMAND);
}
}
void Plugins__Parsing__Verbs__index_normal(grammar_verb *gv, char *headword) {
Plugins__Parsing__Lines__sorted_list_index_normal(gv->sorted_first_line, headword);
}
void Plugins__Parsing__Verbs__index_alias(grammar_verb *gv, char *headword) {
INDEX("&quot;%s&quot;, <i>same as</i> &quot;%s&quot;",
headword, Text__word_text(gv->command_wn));
Index__below_link(Text__word_text(gv->command_wn));
INDEX("<br>");
}
#line 376 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb *Plugins__Parsing__Verbs__named_token_new(int w1, int w2) {
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb) {
if ((gv->gv_is == GV_IS_TOKEN) &&
(Text__compare_word_range(w1, w2, gv->word_ref1, gv->word_ref2)))
return gv;
}
gv = gv_new(GV_IS_TOKEN);
gv->word_ref1 = w1; gv->word_ref2 = w2;
return gv;
}
grammar_verb *Plugins__Parsing__Verbs__named_token_by_name(int w1, int w2) {
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb) {
if ((gv->gv_is == GV_IS_TOKEN) &&
(Text__compare_word_range(w1, w2, gv->word_ref1, gv->word_ref2)))
return gv;
}
return NULL;
}
#line 401 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__index_tokens(void) {
index_tokens_for(-1, -1, "anybody", NULL, NULL, "someone_token", "same as \"[someone]\"");
index_tokens_for(-1, -1, "anyone", NULL, NULL, "someone_token", "same as \"[someone]\"");
index_tokens_for(-1, -1, "anything", NULL, NULL, "things_token", "same as \"[thing]\"");
index_tokens_for(-1, -1, "other things", NULL, NULL, "things_token", NULL);
index_tokens_for(-1, -1, "somebody", NULL, NULL, "someone_token", "same as \"[someone]\"");
index_tokens_for(-1, -1, "someone", NULL, NULL, "someone_token", NULL);
index_tokens_for(-1, -1, "something", NULL, NULL, "things_token", "same as \"[thing]\"");
index_tokens_for(-1, -1, "something preferably held", NULL, NULL, "things_token", NULL);
index_tokens_for(-1, -1, "text", NULL, NULL, "text_token", NULL);
index_tokens_for(-1, -1, "things", NULL, NULL, "things_token", NULL);
index_tokens_for(-1, -1, "things inside", NULL, NULL, "things_token", NULL);
index_tokens_for(-1, -1, "things preferably held", NULL, NULL, "things_token", NULL);
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_TOKEN)
index_tokens_for(gv->word_ref1, gv->word_ref2, NULL,
gv->where_gv_created, gv->sorted_first_line, NULL, NULL);
}
void index_tokens_for(int w1, int w2, char *special, parse_node *where,
grammar_line *defns, char *help, char *explanation) {
Formats__HTML__open_para(ifl, 1, "tight");
INDEX("\"[");
if (special) INDEX("%s", special); else Text__print_raw_text_to_stream(w1, w2, ifl);
INDEX("]\"");
if (where) Index__link(where->word_ref1);
if (help) Index__doc_link(help);
if (explanation) INDEX(" - %s", explanation);
INDEX("</p>");
if (defns) Plugins__Parsing__Lines__index_list_for_token(defns);
}
#line 438 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__translates(int w1, int w2, parse_node *p2) {
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb)
if ((gv->gv_is == GV_IS_TOKEN) &&
(Text__compare_word_range(w1, w2, gv->word_ref1, gv->word_ref2))) {
Problems__sentence_problem(_P_(C25GrammarTranslatedAlready),
"this grammar token has already been translated",
"so there must be some duplication somewhere.");
return;
}
gv = Plugins__Parsing__Verbs__named_token_new(w1, w2);
strcpy(gv->gv_I6_identifier, Text__word_text(p2->word_ref1));
}
void Plugins__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 465 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb *Plugins__Parsing__Verbs__consultation_new(void) {
grammar_verb *gv;
gv = gv_new(GV_IS_CONSULT);
return gv;
}
#line 478 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb *Plugins__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 = gv_new(GV_IS_OBJECT);
PF_S(parsing, subj)->understand_as_this_object = gv;
gv->subj_understood = subj;
return gv;
}
void Plugins__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 = Plugins__Parsing__Lines__list_take_out_one_word_grammar(OUT, gv->first_line);
}
int Plugins__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 505 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb *Plugins__Parsing__Verbs__for_kind(kind *K) {
grammar_verb *gv;
if (Kinds__get_parsing_grammar(K) != NULL)
return Kinds__get_parsing_grammar(K);
gv = gv_new(GV_IS_VALUE);
Kinds__set_parsing_grammar(K, gv);
gv->kind_understood = K;
return gv;
}
#line 521 "inform7/Chapter 25/Grammar Verbs.w"
grammar_verb *Plugins__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 = gv_new(GV_IS_PROPERTY_NAME);
Properties__EitherOr__set_parsing_grammar(prn, gv);
gv->prn_understood = prn;
return gv;
}
#line 537 "inform7/Chapter 25/Grammar Verbs.w"
int Plugins__Parsing__Verbs__is_empty(grammar_verb *gv) {
if ((gv == NULL) || (gv->first_line == NULL)) return TRUE;
return FALSE;
}
void Plugins__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) &&
(Plugins__Parsing__Lines__list_length(gv->first_line) >= MAX_LINES_PER_COMMAND)) {
Problems__sentence_problem(_P_(C25TooManyGrammarLines),
"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 = Plugins__Parsing__Lines__list_add(gv->first_line, gl);
}
#line 564 "inform7/Chapter 25/Grammar Verbs.w"
kind *Plugins__Parsing__Verbs__get_data_type_as_token(grammar_verb *gv) {
return Plugins__Parsing__Tokens__Types__get_data_type_as_token(&(gv->gv_type));
}
#line 573 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__compile_conditions(OUTPUT_STREAM) {
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb) {
current_sentence = gv->where_gv_created;
Plugins__Parsing__Lines__line_list_compile_condition_tokens(OUT, gv->first_line);
}
}
#line 586 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__prepare(void) {
gv_slash_all();
gv_determine_all();
}
#line 596 "inform7/Chapter 25/Grammar Verbs.w"
void 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);
Plugins__Parsing__Lines__line_list_slash(gv->first_line);
gv->slashed = TRUE;
}
}
}
#line 612 "inform7/Chapter 25/Grammar Verbs.w"
void 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;
Plugins__Parsing__Verbs__determine(gv, 0);
gv->determined = TRUE;
}
}
specification *Plugins__Parsing__Verbs__determine(grammar_verb *gv, int depth) {
specification *spec_union = NULL;
current_sentence = gv->where_gv_created;
if (Plugins__Parsing__Tokens__Types__has_return_type(&(gv->gv_type)))
return Plugins__Parsing__Tokens__Types__get_single_type(&(gv->gv_type));
if (depth > NUMBER_CREATED(grammar_verb)) {
Problems__sentence_problem(_P_(C25GrammarIllFounded),
"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 = Plugins__Parsing__Lines__line_list_determine(gv->first_line, depth,
gv->gv_is, gv, gv_is_genuinely_verbal(gv));
LOGIF(GRAMMAR_CONSTRUCTION, "Result of verb $G is $S\n", gv, spec_union);
Plugins__Parsing__Tokens__Types__set_single_type(&(gv->gv_type), spec_union);
return spec_union;
}
#line 670 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__Parsing__Verbs__compile_all(OUTPUT_STREAM) {
grammar_verb *gv;
gv_slash_all();
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)
Plugins__Parsing__Verbs__compile(OUT, gv); /* makes GPRs for designed tokens */
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_COMMAND)
Plugins__Parsing__Verbs__compile(TEMP, gv); /* makes |Verb| directives */
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_OBJECT)
Plugins__Parsing__Verbs__compile(OUT, gv); /* makes routines for use in |parse_name| */
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_CONSULT)
Plugins__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)
Plugins__Parsing__Verbs__compile(OUT, gv); /* makes routines for use in |parse_name| */
compile_slash_gprs(OUT);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
#line 716 "inform7/Chapter 25/Grammar Verbs.w"
void Plugins__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;
Plugins__Parsing__Lines__reset_labels();
switch(gv->gv_is) {
case GV_IS_COMMAND:
gv_compile_Verb_directive_header(OUT, gv);
break;
case GV_IS_TOKEN:
OUT = Plugins__Parsing__Tokens__General__compile_gpr_head(OUT, gv->allocation_id);
break;
case GV_IS_CONSULT:
OUT = Plugins__Parsing__Tokens__General__compile_consult_head(OUT, gv->allocation_id);
break;
case GV_IS_OBJECT:
OUT = Plugins__Parsing__Tokens__General__compile_parse_name_head(OUT, gv->subj_understood, gv);
break;
case GV_IS_VALUE:
break;
case GV_IS_PROPERTY_NAME:
OUT = Plugins__Parsing__Tokens__General__compile_prn_pr_head(OUT, gv->prn_understood);
break;
}
if (gv->gv_is == GV_IS_OBJECT) gv_compile_parse_name_lines(OUT, gv);
else gv_compile_lines(OUT, gv);
switch(gv->gv_is) {
case GV_IS_COMMAND:
WRITE(";\n");
break;
case GV_IS_TOKEN:
OUT = Plugins__Parsing__Tokens__General__compile_gpr_tail(OUT);
break;
case GV_IS_CONSULT:
OUT = Plugins__Parsing__Tokens__General__compile_consult_tail(OUT);
break;
case GV_IS_OBJECT:
OUT = Plugins__Parsing__Tokens__General__compile_parse_name_tail(OUT);
break;
case GV_IS_VALUE:
break;
case GV_IS_PROPERTY_NAME:
OUT = Plugins__Parsing__Tokens__General__compile_prn_pr_tail(OUT, gv->prn_understood);
break;
}
}
#line 776 "inform7/Chapter 25/Grammar Verbs.w"
void 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);
gv_compile_lines(OUT, PF_S(parsing, subj)->understand_as_this_object);
inference_subject *infs;
for (infs = World__Subjects__narrowest_broader_subject(subj);
infs; infs = World__Subjects__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);
gv_compile_lines(OUT, PF_S(parsing, infs)->understand_as_this_object);
}
}
}
#line 799 "inform7/Chapter 25/Grammar Verbs.w"
void gv_compile_lines(OUTPUT_STREAM, grammar_verb *gv) {
Plugins__Parsing__Lines__list_assert_ownership(gv->first_line, gv); /* Mark for later indexing */
sort_grammar_verb(gv); /* Phase III for the GLs in the GV happens here */
Plugins__Parsing__Lines__sorted_line_list_compile(OUT, gv->sorted_first_line,
gv->gv_is, gv, gv_is_genuinely_verbal(gv)); /* And Phase IV here */
}
#line 814 "inform7/Chapter 25/Grammar Verbs.w"
void sort_grammar_verb(grammar_verb *gv) {
if (gv->sorted_first_line == NULL)
gv->sorted_first_line = Plugins__Parsing__Lines__list_sort(gv->first_line);
}
#line 80 "inform7/Chapter 25/Grammar Lines.w"
grammar_line *Plugins__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) Plugins__Actions__add_gl(ac, gl);
gl->mistaken = FALSE;
gl->mistake_response_wn = -1;
gl->next_with_action = NULL;
gl->next_line = NULL;
gl->tokens = token_list;
gl->where_grammar_specified = current_sentence;
gl->gl_type = Plugins__Parsing__Tokens__Types__new(TRUE);
gl->lexeme_count = -1; /* no count made as yet */
gl->reversed = reversed;
gl->pluralised = pluralised;
gl->understand_when_w1 = -1;
gl->understand_when_w2 = -1;
gl->suppress_compilation = FALSE;
gl->general_sort_bonus = UNCALCULATED_BONUS;
gl->understanding_sort_bonus = UNCALCULATED_BONUS;
return gl;
}
void Plugins__Parsing__Lines__log(grammar_line *gl) {
LOG("<GL%d:$W>", gl->allocation_id,
gl->tokens->word_ref1, gl->tokens->word_ref2);
}
void Plugins__Parsing__Lines__set_single_type(grammar_line *gl, specification *gl_value) {
Plugins__Parsing__Tokens__Types__set_single_type(&(gl->gl_type), gl_value);
}
#line 123 "inform7/Chapter 25/Grammar Lines.w"
int Plugins__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 *Plugins__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 *Plugins__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 25/Grammar Lines.w"
void Plugins__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) {
gl_compile_condition_token_as_needed(OUT, gl);
gl_compile_mistake_token_as_needed(OUT, gl);
}
}
#line 187 "inform7/Chapter 25/Grammar Lines.w"
int understand_condition_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = 0; specification_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 25/Grammar Lines.w"
Problems__sentence_problem(_P_(C25WhenAction),
"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 25/Grammar Lines.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 203 "inform7/Chapter 25/Grammar Lines.w"
Problems__sentence_problem(_P_(C25BadWhen),
"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 25/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 25/Grammar Lines.w"
#line 212 "inform7/Chapter 25/Grammar Lines.w"
int spec_non_action_condition_NTMR(int w1, int w2, int *X, void **XP) {
#line 213 "inform7/Chapter 25/Grammar Lines.w"
int old_state = Plugins__Actions__Patterns__suppress();
Specifications__warn_expression_cache();
specification *spec = parse_with_cache(w1, w2, CONDITION_EXPCON);
Specifications__warn_expression_cache();
Plugins__Actions__Patterns__resume(old_state);
if (Specifications__is_UNKNOWN(spec)) return FALSE;
*XP = spec;
return TRUE;
}
#line 231 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__set_understand_when(grammar_line *gl, int w1, int w2) {
gl->understand_when_w1 = w1;
gl->understand_when_w2 = w2;
}
void gl_compile_condition_token_as_needed(OUTPUT_STREAM, grammar_line *gl) {
if (gl->understand_when_w1 >= 0) {
current_sentence = gl->where_grammar_specified;
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "Cond_Token_%d", gl->allocation_id);
OUT = Code__Routines__begin(OUT, i6_routine_identifier);
specification *spec = NULL;
current_sentence = gl->where_grammar_specified;
if (parse_nt_against_word_range(understand_condition_NTM, gl->understand_when_w1, gl->understand_when_w2, NULL, NULL))
spec = specification_cond_NTMV;
if (spec) {
if (Plugins__Actions__Patterns__validate_when(spec) == FALSE)
{
#line 203 "inform7/Chapter 25/Grammar Lines.w"
Problems__sentence_problem(_P_(C25BadWhen),
"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 251 "inform7/Chapter 25/Grammar Lines.w"
else {
WRITE("if ("); Specifications__compile(OUT, spec);
WRITE(") return GPR_PREPOSITION;\n");
WRITE("return GPR_FAIL;\n");
}
}
OUT = Code__Routines__end(OUT);
}
}
void gl_compile_extra_token_for_condition(OUTPUT_STREAM, grammar_line *gl,
int gv_is, int current_label) {
if (gl->understand_when_w1 >= 0) {
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 296 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__set_mistake(grammar_line *gl, int wn) {
gl->mistaken = TRUE;
gl->mistake_response_wn = wn;
}
void gl_compile_mistake_token_as_needed(OUTPUT_STREAM, grammar_line *gl) {
if (gl->mistaken) {
OUT = Code__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 = Code__Routines__end(OUT);
}
}
void 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 gl_compile_result_of_mistake(OUTPUT_STREAM, grammar_line *gl) {
if (gl->mistaken) { WRITE(" -> MistakeAction\n"); return TRUE; }
return FALSE;
}
void Plugins__Parsing__Lines__MistakeActionSub_routine(OUTPUT_STREAM) {
OUT = Code__Routines__begin(OUT, "MistakeActionSub");
WRITE("switch(understand_as_mistake_number) {\n"); INDENT;
grammar_line *gl;
LOOP_OVER(gl, grammar_line)
if (gl->mistaken) {
if (gl->mistake_response_wn >= 0) {
current_sentence = gl->where_grammar_specified;
specification *spec = NULL;
if (parse_nt_against_word_range(spec_value_NTM, gl->mistake_response_wn, gl->mistake_response_wn, NULL, NULL))
spec = most_recent_result_p;
else spec = Specifications__Unknown__new(
gl->mistake_response_wn, gl->mistake_response_wn);
WRITE("%d: ParserError(", 100+gl->allocation_id);
Specifications__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 = Code__Routines__end(OUT);
}
#line 360 "inform7/Chapter 25/Grammar Lines.w"
int gl_contains_single_unconditional_word(grammar_line *gl) {
parse_node *pn = gl->tokens->down;
if ((pn)
&& (pn->next == NULL)
&& (Parser__Nodes__int_annotation(pn, slash_class_ANNOT) == 0)
&& (Parser__Nodes__int_annotation(pn, grammar_token_literal_ANNOT))
&& (gl->pluralised == FALSE)
&& (gl->understand_when_w1 < 0))
return pn->word_ref1;
return -1;
}
#line 382 "inform7/Chapter 25/Grammar Lines.w"
grammar_line *Plugins__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 = gl_contains_single_unconditional_word(gl);
if (wn >= 0) {
if (OUT) {
Formats__Inform6__compile_dictionary_word(OUT, Text__word_text(wn), FALSE);
WRITE(" ");
}
gl->suppress_compilation = TRUE;
} else glp = gl;
}
return list_head;
}
#line 403 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__line_list_slash(grammar_line *gl_head) {
grammar_line *gl;
for (gl = gl_head; gl; gl = gl->next_line) {
slash_grammar_line(gl);
}
}
#line 423 "inform7/Chapter 25/Grammar Lines.w"
void 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)
Parser__Nodes__annotate_int(pn, slash_class_ANNOT, 0);
parse_node *class_start = NULL;
for (pn = gl->tokens->down; pn; pn = pn->next) {
if ((pn->next != NULL) &&
(Text__word(pn->next->word_ref1) == FORWARDSLASH_V) &&
(pn->next->word_ref1 == pn->next->word_ref2)) { /* slash follows: */
if (Parser__Nodes__int_annotation(pn, slash_class_ANNOT) == 0) {
class_start = pn; alternatives_group++; /* start new equiv class */
Parser__Nodes__annotate_int(class_start, slash_dash_dash_ANNOT, FALSE);
}
Parser__Nodes__annotate_int(pn, slash_class_ANNOT,
alternatives_group); /* make two sides of slash equiv */
if (pn->next->next)
Parser__Nodes__annotate_int(pn->next->next, slash_class_ANNOT, alternatives_group);
if ((pn->next->next) &&
(Text__word(pn->next->next->word_ref1) == DOUBLEDASH_V) &&
(pn->next->next->word_ref1 == pn->next->next->word_ref2)) { /* -- follows: */
Parser__Nodes__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 ((Parser__Nodes__int_annotation(pn, slash_class_ANNOT) > 0) &&
(Parser__Nodes__int_annotation(pn, grammar_token_literal_ANNOT) == FALSE)) {
Problems__sentence_problem(_P_(C25OverAmbitiousSlash),
"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 = Parser__Nodes__int_annotation(pn, slash_class_ANNOT);
if (i > 0)
while ((pn->next) && (Parser__Nodes__int_annotation(pn->next, slash_class_ANNOT) == i))
pn = pn->next;
gl->lexeme_count++;
}
LOGIF(GRAMMAR_CONSTRUCTION, "Slashed as:\n$T", gl->tokens);
}
#line 500 "inform7/Chapter 25/Grammar Lines.w"
specification *Plugins__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;
specification *spec_union = NULL;
LOGIF(GRAMMAR_CONSTRUCTION, "Determining GL list for $G\n", gv);
for (gl = list_head; gl; gl = gl->next_line) {
specification *spec_of_line =
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 (Specifications__Matching__can_we_match_value_descriptions(spec_union, spec_of_line) == ALWAYS_MATCH) {
spec_union = spec_of_line; /* here |spec_of_line| was a wider type */
continue;
}
if (Specifications__Matching__can_we_match_value_descriptions(spec_of_line, spec_union) == ALWAYS_MATCH) {
continue; /* here |spec_union| was already wide enough */
}
}
if (Plugins__Parsing__Verbs__allow_mixed_lines(gv)) continue;
current_sentence = gl->where_grammar_specified;
Problems__sentence_problem(_P_(C25MixedOutcome),
"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: $S\n");
return spec_union;
}
#line 553 "inform7/Chapter 25/Grammar Lines.w"
specification *gl_determine(grammar_line *gl, int depth,
int gv_is, grammar_verb *gv, int genuinely_verbal) {
specification *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 (Parser__Nodes__type(pn) != TOKEN_NT)
internal_error("Bogus node types on grammar");
spec = Plugins__Parsing__Tokens__determine(pn, depth);
LOGIF(GRAMMAR_CONSTRUCTION, "Result of token <$W> is $S\n",
pn->word_ref1, pn->word_ref2, spec);
if (spec) {
if ((Specifications__Values__is_generic_CONSTANT(spec)) &&
(Kinds__eq(Specifications__get_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 +=
Plugins__Parsing__Tokens__Types__add_type(&(gl->gl_type), spec,
Plugins__Parsing__Tokens__is_multiple(pn));
} else nulls_count++;
if (Plugins__Parsing__Tokens__is_multiple(pn)) multiples++;
}
if (multiples > 1)
Problems__sentence_problem(_P_(C25MultipleMultiples),
"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 = Plugins__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 = Plugins__Parsing__Tokens__Types__get_single_type(&(gl->gl_type));
else Problems__sentence_problem(_P_(C25TwoValuedToken),
"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 $S\n",
gl, gl->lexeme_count, gl->general_sort_bonus, nrv,
gl->understanding_sort_bonus, spec);
return spec;
}
#line 629 "inform7/Chapter 25/Grammar Lines.w"
grammar_line *Plugins__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 (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 (grammar_line_must_precede(gl, gl2)) {
gl3->sorted_next_line = gl;
gl->sorted_next_line = gl2;
break;
}
}
}
return sorted_head;
}
#line 822 "inform7/Chapter 25/Grammar Lines.w"
int 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) 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 = Plugins__Parsing__Tokens__Types__must_precede(&(L1->gl_type), &(L2->gl_type));
if (cs != NOT_APPLICABLE) return cs;
if ((L1->understand_when_w1 >= 0) && (L2->understand_when_w1 < 0)) return TRUE;
if ((L1->understand_when_w1 < 0) && (L2->understand_when_w1 >= 0)) return FALSE;
return FALSE;
}
#line 879 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__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)
compile_grammar_line(OUT, gl, gv_is, gv, genuinely_verbal);
OUTDENT;
}
#line 895 "inform7/Chapter 25/Grammar Lines.w"
int current_grammar_block = 0;
int current_label = 1;
int GV_IS_VALUE_instance_mode = FALSE;
void Plugins__Parsing__Lines__reset_labels(void) {
current_label = 1;
}
#line 911 "inform7/Chapter 25/Grammar Lines.w"
void 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("* ");
gl_compile_extra_token_for_condition(OUT, gl, gv_is, current_label);
gl_compile_extra_token_for_mistake(OUT, gl, gv_is, current_label);
pn = gl->tokens->down;
if ((genuinely_verbal) && (pn)) {
if (Parser__Nodes__int_annotation(pn, slash_class_ANNOT) != 0) {
Problems__sentence_problem(_P_(C25SlashedCommand),
"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 == ");
Plugins__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;
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 (gl_compile_result_of_mistake(OUT, gl)) break;
WRITE(" -> %s", Plugins__Actions__identifier(gl->resulting_action));
if (gl->reversed) {
if (token_values < 2) {
Problems__sentence_problem(_P_(C25CantReverseOne),
"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");
Plugins__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:
Plugins__Parsing__Tokens__General__after_gl_failed(OUT, current_label, gl->pluralised);
break;
case GV_IS_VALUE:
WRITE("parsed_number = ");
Plugins__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 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 ((Plugins__Parsing__Tokens__is_text(pn)) && (pn->next) &&
(Plugins__Parsing__Tokens__is_literal(pn->next) == FALSE)) {
Problems__sentence_problem(_P_(C25TextFollowedBy),
"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 ((Parser__Nodes__get_grammar_token_relation(pn)) && (gv_is != GV_IS_OBJECT)) {
Problems__sentence_problem(_P_(C25GrammarObjectlessRelation),
"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 (Parser__Nodes__int_annotation(pn, slash_class_ANNOT) != 0) { /* in a multi-token lexeme */
if ((pn->next == NULL) ||
(Parser__Nodes__int_annotation(pn->next, slash_class_ANNOT) !=
Parser__Nodes__int_annotation(pn, slash_class_ANNOT)))
last_token_in_lexeme = TRUE;
if (Parser__Nodes__int_annotation(pn, slash_class_ANNOT) != lexeme_equivalence_class) {
first_token_in_lexeme = TRUE;
empty_text_allowed_in_lexeme =
Parser__Nodes__int_annotation(pn, slash_dash_dash_ANNOT);
}
lexeme_equivalence_class = Parser__Nodes__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) &&
(Parser__Nodes__int_annotation(pn->next, slash_class_ANNOT) ==
Parser__Nodes__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 =
Plugins__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 compile_slash_gprs(OUTPUT_STREAM) {
slash_gpr *sgpr;
LOOP_OVER(sgpr, slash_gpr) {
OUT = Code__Routines__begin_numbered(OUT, "SlashGPR_%d", sgpr->allocation_id);
Code__LocalVariables__add_internal_local_c("group_wn",
"first word matched against A/B/C/.../-- disjunction");
compile_token_line(OUT, TRUE, sgpr->first_choice, sgpr->last_choice, GV_IS_TOKEN, FALSE, NULL, NULL);
WRITE("return GPR_PREPOSITION;\n");
OUT = Code__Routines__end(OUT);
}
}
#line 1155 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__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)
gl_index_normal(gl, headword);
}
void gl_index_normal(grammar_line *gl, char *headword) {
action_name *an = gl->resulting_action;
if (an == NULL) return;
Index__anchor(headword);
if (Plugins__Actions__is_out_of_world(an))
INDEX("<font color=\"#800000\">");
INDEX("&quot;");
Plugins__Actions__Index__verb_definition(Text__word_text(gl->original_text), headword, -1);
INDEX("&quot;");
Index__link(gl->original_text);
INDEX(" - <i>");
Text__print_raw_text_to_stream(an->word_ref1, an->word_ref2, ifl);
Index__detail_link("A", an->allocation_id, TRUE);
if (gl->reversed) INDEX(" (reversed)");
INDEX("</i>");
if (Plugins__Actions__is_out_of_world(an))
INDEX("</font>");
INDEX("<br>");
}
#line 1195 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__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 1204 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__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 1215 "inform7/Chapter 25/Grammar Lines.w"
int Plugins__Parsing__Lines__index_list_with_action(grammar_line *gl) {
int said_something = FALSE;
while (gl != NULL) {
if (gl->belongs_to_gv) {
int vwn = Plugins__Parsing__Verbs__get_verb_wn(gl->belongs_to_gv);
char *trueverb = NULL;
if (vwn != -1) trueverb = Text__word_text(vwn);
Formats__HTML__open_para(ifl, 2, "hanging");
INDEX("&quot;");
Plugins__Actions__Index__verb_definition(
Text__word_text(gl->original_text), trueverb, vwn);
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 1240 "inform7/Chapter 25/Grammar Lines.w"
void Plugins__Parsing__Lines__index_list_for_token(grammar_line *gl) {
int k = 0;
while (gl != NULL) {
if (gl->belongs_to_gv) {
int vwn = Plugins__Parsing__Verbs__get_verb_wn(gl->belongs_to_gv);
char *trueverb = NULL;
if (vwn != -1) trueverb = Text__word_text(vwn);
Formats__HTML__open_para(ifl, 2, "hanging");
if (k++ == 0) INDEX("="); else INDEX("or");
INDEX(" &quot;");
Plugins__Actions__Index__verb_definition(
Text__word_text(gl->original_text), trueverb, -1);
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 25/Grammar Types.w"
grammar_type Plugins__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 25/Grammar Types.w"
int Plugins__Parsing__Tokens__Types__add_type(grammar_type *gty, specification *spec,
int multiple_flag) {
switch((gty->no_resulting_values)++) {
case 0:
gty->first_type = spec;
gty->first_multiplicity = multiple_flag;
return 10*(Specifications__get_data(spec, GRAMMAR_TOKEN_SCORE_SPDATA));
case 1:
gty->second_type = spec;
gty->second_multiplicity = multiple_flag;
return Specifications__get_data(spec, GRAMMAR_TOKEN_SCORE_SPDATA);
case 2:
Problems__sentence_problem(_P_(C25ThreeValuedLine),
"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 Plugins__Parsing__Tokens__Types__has_return_type(grammar_type *gty) {
if (gty->no_resulting_values == -1) return FALSE;
return TRUE;
}
int Plugins__Parsing__Tokens__Types__get_no_resulting_values(grammar_type *gty) {
return gty->no_resulting_values;
}
specification *Plugins__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 Plugins__Parsing__Tokens__Types__set_single_type(grammar_type *gty, specification *spec) {
if (spec == NULL) gty->no_resulting_values = 0;
else {
gty->no_resulting_values = 1;
gty->first_type = spec;
}
}
void Plugins__Parsing__Tokens__Types__compile_to_string(OUTPUT_STREAM, grammar_type *gty) {
Specifications__compile(OUT, gty->first_type);
}
kind *Plugins__Parsing__Tokens__Types__get_data_type_as_token(grammar_type *gty) {
if (gty->no_resulting_values > 0) {
if ((Specifications__species_is(gty->first_type, CONSTANT_SPC)) ||
(Specifications__Values__is_generic_CONSTANT(gty->first_type)))
return Specifications__get_kind(gty->first_type);
}
return NULL;
}
#line 109 "inform7/Chapter 25/Grammar Types.w"
int Plugins__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 62 "inform7/Chapter 25/Grammar Tokens.w"
int grammar_token_breaking_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 66 "inform7/Chapter 25/Grammar Tokens.w"
#line 80 "inform7/Chapter 25/Grammar Tokens.w"
void Plugins__Parsing__Tokens__break_into_tokens(parse_node *pn, int w1, int w2) {
parse_nt_against_word_range(grammar_token_breaking_NTM, w1, w2, NULL, NULL);
switch (most_recent_result) {
case NOT_APPLICABLE: {
int l1, l2, r1, r2;
GET_RW(grammar_token_breaking_NTM, 1, l1, l2);
GET_RW(grammar_token_breaking_NTM, 2, r1, r2);
Plugins__Parsing__Tokens__break_into_tokens(pn, l1, l2);
Plugins__Parsing__Tokens__break_into_tokens(pn, r1, r2);
break;
}
case TRUE:
Text__dequote_word(w1);
if (*(Text__word_text(w1)) == 0) return;
Text__feed_into_lexer(Text__word_text(w1), FALSE, GRAMMAR_PUNCTUATION_MARKS);
w1 = lexer_feed_w1; w2 = lexer_feed_w2;
int i;
for (i=w1; i<=w2; i++) {
parse_node *newpn = Parser__Sentences__NPs__new_raw(i, i);
Parser__Nodes__set_node_type(newpn, TOKEN_NT);
Parser__Nodes__annotate_int(newpn, grammar_token_literal_ANNOT, TRUE);
Parser__Nodes__graft(newpn, pn);
}
break;
case FALSE: {
parse_node *newpn = Parser__Sentences__NPs__new_raw(w1, w2);
Parser__Nodes__set_node_type(newpn, TOKEN_NT);
Parser__Nodes__annotate_int(newpn, grammar_token_literal_ANNOT, FALSE);
Parser__Nodes__graft(newpn, pn);
break;
}
}
}
int Plugins__Parsing__Tokens__is_literal(parse_node *pn) {
return Parser__Nodes__int_annotation(pn, grammar_token_literal_ANNOT);
}
#line 123 "inform7/Chapter 25/Grammar Tokens.w"
int Plugins__Parsing__Tokens__is_multiple(parse_node *pn) {
switch (Parser__Nodes__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 137 "inform7/Chapter 25/Grammar Tokens.w"
int Plugins__Parsing__Tokens__is_text(parse_node *pn) {
switch (Parser__Nodes__int_annotation(pn, grammar_token_code_ANNOT)) {
case TOPIC_TOKEN_GTC:
return TRUE;
}
return FALSE;
}
#line 150 "inform7/Chapter 25/Grammar Tokens.w"
int 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 168 "inform7/Chapter 25/Grammar Tokens.w"
char *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 *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 202 "inform7/Chapter 25/Grammar Tokens.w"
kind *kind_for_special_token(int gtc) {
if (gtc == TOPIC_TOKEN_GTC) return K_understanding;
return K_object;
}
#line 210 "inform7/Chapter 25/Grammar Tokens.w"
int grammar_token_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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_STUFF_GTC; specification_s_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = ANY_STUFF_GTC; specification_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; specification_s_NTMV = Specifications__Conditions__new_DESCRIPTION_of(K_thing);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = ANY_STUFF_GTC; specification_s_NTMV = Specifications__Conditions__new_DESCRIPTION_of(K_person);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = ANY_STUFF_GTC; specification_s_NTMV = Specifications__Conditions__new_DESCRIPTION_of(K_person);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = ANY_STUFF_GTC; specification_s_NTMV = Specifications__Conditions__new_DESCRIPTION_of(K_room);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = RELATED_GTC; *XP = Semantics__BPs__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 254 "inform7/Chapter 25/Grammar Tokens.w"
*X = RELATED_GTC; *XP = NULL;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C25GrammarBadRelation));
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 220 "inform7/Chapter 25/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; specification_s_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12: *X = STUFF_GTC; specification_s_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13: *X = STUFF_GTC; specification_s_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14:
{
#line 344 "inform7/Chapter 25/Grammar Tokens.w"
*X = STUFF_GTC;
Parser__Nodes__log_subtree(current_sentence, 0);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__quote_kind_of(3, RP[1]);
Problems__handmade_problem(_P_(C25BizarreToken));
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 225 "inform7/Chapter 25/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15:
{
#line 359 "inform7/Chapter 25/Grammar Tokens.w"
*X = STUFF_GTC;
Parser__Nodes__log_subtree(current_sentence, 0);
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C25UnknownToken));
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 226 "inform7/Chapter 25/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 227 "inform7/Chapter 25/Grammar Tokens.w"
int standard_grammar_token_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 267 "inform7/Chapter 25/Grammar Tokens.w"
*X = TOPIC_TOKEN_GTC;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C25UseTextNotTopic));
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 238 "inform7/Chapter 25/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10:
{
#line 267 "inform7/Chapter 25/Grammar Tokens.w"
*X = TOPIC_TOKEN_GTC;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C25UseTextNotTopic));
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 239 "inform7/Chapter 25/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11:
{
#line 286 "inform7/Chapter 25/Grammar Tokens.w"
*X = MULTI_TOKEN_GTC;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C25UseThingNotObject));
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 240 "inform7/Chapter 25/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12:
{
#line 286 "inform7/Chapter 25/Grammar Tokens.w"
*X = MULTI_TOKEN_GTC;
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, w1, w2);
Problems__handmade_problem(_P_(C25UseThingNotObject));
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 241 "inform7/Chapter 25/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13:
{
#line 300 "inform7/Chapter 25/Grammar Tokens.w"
*X = HELD_TOKEN_GTC;
incompatible_change_problem(
"something held", "something", "something preferably held");
}
#line 242 "inform7/Chapter 25/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14:
{
#line 307 "inform7/Chapter 25/Grammar Tokens.w"
*X = MULTIHELD_TOKEN_GTC;
incompatible_change_problem(
"things held", "things", "things preferably held");
}
#line 243 "inform7/Chapter 25/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 244 "inform7/Chapter 25/Grammar Tokens.w"
int named_grammar_token_NTMR(int w1, int w2, int *X, void **XP) {
#line 246 "inform7/Chapter 25/Grammar Tokens.w"
grammar_verb *gv = Plugins__Parsing__Verbs__named_token_by_name(w1, w2);
if (gv) { *XP = gv; return TRUE; }
return FALSE;
}
#line 315 "inform7/Chapter 25/Grammar Tokens.w"
void 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__handmade_problem(_P_(C25ObsoleteHeldTokens));
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 374 "inform7/Chapter 25/Grammar Tokens.w"
specification *Plugins__Parsing__Tokens__determine(parse_node *pn, int depth) {
int w1, w2;
specification *spec = NULL;
if (Parser__Nodes__int_annotation(pn, grammar_token_literal_ANNOT)) return NULL;
w1 = pn->word_ref1; w2 = pn->word_ref2;
grammar_verb_named_NTMV = NULL;
parse_nt_against_word_range(grammar_token_NTM, w1, w2, NULL, NULL);
switch (most_recent_result) {
case NAMED_TOKEN_GTC:
{
#line 396 "inform7/Chapter 25/Grammar Tokens.w"
specification *val = grammar_verb_to_understanding_spec(grammar_verb_named_NTMV);
spec = Plugins__Parsing__Verbs__determine(grammar_verb_named_NTMV, depth+1); /* this is where Phase II recurses */
Parser__Nodes__set_grammar_value(pn, val);
}
#line 383 "inform7/Chapter 25/Grammar Tokens.w"
; break;
case ANY_STUFF_GTC:
{
#line 403 "inform7/Chapter 25/Grammar Tokens.w"
spec = specification_s_NTMV;
if (Specifications__species_is(spec, DESCRIPTION_SPC)) {
Parser__Nodes__annotate_int(pn, grammar_token_code_ANNOT,
Plugins__Parsing__Tokens__Filters__new_id(spec, TRUE));
Parser__Nodes__set_grammar_value(pn, spec);
}
}
#line 384 "inform7/Chapter 25/Grammar Tokens.w"
; break;
case RELATED_GTC:
{
#line 413 "inform7/Chapter 25/Grammar Tokens.w"
binary_predicate *bp = most_recent_result_p;
if (bp) Parser__Nodes__set_grammar_token_relation(pn, bp);
}
#line 385 "inform7/Chapter 25/Grammar Tokens.w"
; break;
case STUFF_GTC:
{
#line 419 "inform7/Chapter 25/Grammar Tokens.w"
spec = specification_s_NTMV;
Parser__Nodes__set_grammar_value(pn, spec);
if (Specifications__describes_an_object_vaguely_or_exactly(spec)) {
Specifications__set_data(spec, GRAMMAR_TOKEN_SCORE_SPDATA, 5);
Parser__Nodes__annotate_int(pn, grammar_token_code_ANNOT,
Plugins__Parsing__Tokens__Filters__new_id(spec, FALSE));
}
}
#line 386 "inform7/Chapter 25/Grammar Tokens.w"
; break;
default:
{
#line 430 "inform7/Chapter 25/Grammar Tokens.w"
int p = most_recent_result;
spec = Specifications__Values__new_generic_CONSTANT(kind_for_special_token(p));
spec->word_ref1 = w1; spec->word_ref2 = w2;
Specifications__set_data(spec, GRAMMAR_TOKEN_SCORE_SPDATA, gsb_for_special_token(p));
Parser__Nodes__set_grammar_value(pn, spec);
Parser__Nodes__annotate_int(pn, grammar_token_code_ANNOT, p);
}
#line 387 "inform7/Chapter 25/Grammar Tokens.w"
; break;
}
if (spec)
{
#line 440 "inform7/Chapter 25/Grammar Tokens.w"
if (Specifications__Values__is_generic_CONSTANT(spec)) {
kind *K = Specifications__get_kind(spec);
if ((Kinds__le(K, K_object) == FALSE) &&
(Kinds__eq(K, K_understanding) == FALSE) &&
(Kinds__request_I6_GPR(K) == FALSE)) {
Problems__quote_source(1, current_sentence);
Problems__quote_words(2, pn->word_ref1, pn->word_ref2);
Problems__handmade_problem(_P_(C25UnparsableKind));
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 389 "inform7/Chapter 25/Grammar Tokens.w"
;
return spec;
}
#line 472 "inform7/Chapter 25/Grammar Tokens.w"
int ol_loop_counter = 0;
kind *Plugins__Parsing__Tokens__compile(OUTPUT_STREAM, parse_node *pn, int code_mode,
char *failure_label, int consult_mode) {
int wn = pn->word_ref1;
specification *spec;
binary_predicate *bp;
grammar_verb *gv;
if (Parser__Nodes__int_annotation(pn, grammar_token_literal_ANNOT)) {
if (code_mode) {
WRITE("if (NextWordStopped() ~= ");
Formats__Inform6__compile_dictionary_word(OUT, Text__word_text(wn), FALSE);
WRITE(") jump %s;\n", failure_label);
} else {
Formats__Inform6__compile_dictionary_word(OUT, Text__word_text(wn), FALSE);
}
return NULL;
}
bp = Parser__Nodes__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__handmade_problem(_P_(C25RelatedByEquality));
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 ((Semantics__BPs__get_reversal(bp) == R_containment) ||
(Semantics__BPs__get_reversal(bp) == R_support) ||
(Semantics__BPs__get_reversal(bp) == a_has_b_predicate) ||
(Semantics__BPs__get_reversal(bp) == R_wearing) ||
(Semantics__BPs__get_reversal(bp) == R_carrying)) {
if (Semantics__BPs__get_reversal(bp) == R_carrying)
WRITE("if (self has worn) jump %s;\n", failure_label);
if (Semantics__BPs__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 (Semantics__BPs__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 = Semantics__BPs__get_test_function(bp);
LOGIF(GRAMMAR_CONSTRUCTION, "Read I6s $i from $2\n", i6s, bp);
if ((i6s == NULL) && (Semantics__BPs__get_test_function(Semantics__BPs__get_reversal(bp)))) {
reverse = TRUE;
i6s = Semantics__BPs__get_test_function(Semantics__BPs__get_reversal(bp));
LOGIF(GRAMMAR_CONSTRUCTION, "But read I6s $i from reversal\n", i6s);
}
if (i6s) {
kind *K = Semantics__BPs__term_kind(bp, 1);
if (Kinds__lt(K, K_object)) {
LOGIF(GRAMMAR_CONSTRUCTION, "Term 1 of BP is $u\n", K);
WRITE("objectloop (rv ofclass %s) {\n",
Kinds__I6_classname(K)); INDENT;
WRITE("if ((");
if (reverse)
Code__Schemas__expand_textual(i6s, OUT, "rv", "self");
else
Code__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__handmade_problem(_P_(C25GrammarValueRelation));
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 = Semantics__BPs__get_i6_storage_property(bp);
reverse = FALSE;
if (Semantics__BPs__is_the_wrong_way_round(bp)) reverse = TRUE;
if (Semantics__BPs__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 = Semantics__BPs__term_kind(bp, 1);
if (Kinds__le(K, K_object) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, pn);
Problems__quote_kind(3, K);
Problems__handmade_problem(_P_(C25GrammarValueRelation2));
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__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", Semantics__BPs__get_reversal(bp));
internal_error("Can't implement this relation");
}
}
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 = Parser__Nodes__get_grammar_value(pn);
if (spec == NULL) Plugins__Parsing__Tokens__determine(pn, 10);
spec = Parser__Nodes__get_grammar_value(pn);
if (spec == NULL) {
Parser__Nodes__log_subtree(pn, 1);
internal_error("NULL result of non-preposition token");
}
if ((Specifications__Values__is_generic_CONSTANT(spec)) &&
(Kinds__le(Specifications__get_kind(spec), K_object) == FALSE) &&
(Kinds__eq(Specifications__get_kind(spec), K_understanding) == FALSE)) {
kind *K = Specifications__get_kind(spec);
if (Kinds__offers_I6_GPR(K)) {
char *i6_gpr_name = Kinds__get_explicit_I6_GPR(K);
if (code_mode) {
WRITE("w = ParseTokenStopped(GPR_TT, ");
if (i6_gpr_name != NULL) WRITE(i6_gpr_name);
else Plugins__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 Plugins__Parsing__Tokens__Values__gprv_compile(OUT, K);
}
return Specifications__get_kind(spec);
}
internal_error("Let an invalid type token through");
}
if (Specifications__Conditions__is_complex_DESCRIPTION(spec)) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, pn);
Problems__handmade_problem(_P_(C25OverComplexToken));
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 container "
"which is open]' will probably not be allowed. It may be "
"possible to rephrase in a simple adjectives-plus-noun "
"way, as in '[open container]', but if not, then you may "
"may wish to investigate writing a new token.");
Problems__issue_problem_end();
return K_object;
} else {
int gtc = Parser__Nodes__int_annotation(pn, grammar_token_code_ANNOT);
kind *K = NULL;
if (gtc < 0) {
char *i6_token = i6_token_for_special_token(gtc);
char *i6_token_constant = i6_constant_for_special_token(gtc);
K = kind_for_special_token(gtc);
if (code_mode) {
if ((consult_mode) && (gtc == TOPIC_TOKEN_GTC)) {
Problems__sentence_problem(_P_(C25TextTokenRestricted),
"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__species_is(spec, DESCRIPTION_SPC)) {
if (code_mode) {
WRITE("w = ParseTokenStopped(");
Plugins__Parsing__Tokens__Filters__compile_id(OUT, gtc, TRUE);
WRITE(");\n");
WRITE("if (w == GPR_FAIL) jump %s; rv = w;\n",
failure_label);
} else Plugins__Parsing__Tokens__Filters__compile_id(OUT, gtc, FALSE);
K = Specifications__get_kind_referred_to(spec);
} else {
if (Specifications__species_is(spec, CONSTANT_SPC)) {
if (Specifications__Values__is_CONSTANT_of_kind(spec, K_understanding)) {
gv = understanding_spec_to_grammar_verb(spec);
if (code_mode) {
WRITE("w = ParseTokenStopped(GPR_TT, ");
Plugins__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 Plugins__Parsing__Verbs__compile_i6_token(OUT, gv);
K = Plugins__Parsing__Verbs__get_data_type_as_token(gv);
}
if (Specifications__Values__is_CONSTANT_object(spec)) {
if (code_mode) {
WRITE("w = ParseTokenStopped(");
Plugins__Parsing__Tokens__Filters__compile_id(OUT, gtc, TRUE);
WRITE(");\n");
WRITE("if (w == GPR_FAIL) jump %s; rv = w;\n",
failure_label);
} else Plugins__Parsing__Tokens__Filters__compile_id(OUT, gtc, FALSE);
K = K_object;
}
} else K = K_object;
}
}
return K;
}
}
#line 32 "inform7/Chapter 25/Noun Filter Tokens.w"
noun_filter_token *nft_new(specification *spec, int global_scope) {
noun_filter_token *nft = CREATE(noun_filter_token);
nft->the_filter = spec;
nft->global_scope_flag = global_scope;
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 nft_compile_routine_name(OUTPUT_STREAM, noun_filter_token *nft) {
WRITE("%s", nft->nft_routine_name);
}
void nft_compile_routine(OUTPUT_STREAM, noun_filter_token *nft) {
specification *noun_var = Specifications__Storage__new_actual_NONLOCAL_VARIABLE(I6_noun_VAR);
kind *R = Specifications__get_kind_referred_to(nft->the_filter);
kind *K = Data__NonlocalVariables__kind(I6_noun_VAR);
Data__NonlocalVariables__set_kind(I6_noun_VAR, R);
if (Kinds__le(R, K_object) == FALSE) nft->parse_using_gpr = TRUE;
OUT = Code__Routines__begin(OUT, nft->nft_routine_name);
if (nft->parse_using_gpr) {
Code__LocalVariables__add_internal_local_c("v", "value parsed");
Code__LocalVariables__add_internal_local_c("n", "saved value of noun");
WRITE("v = ");
char *explicit = Kinds__get_explicit_I6_GPR(R);
if (explicit) WRITE("%s", explicit);
else Plugins__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) {
Code__LocalVariables__add_internal_local_c("obj", "object loop variable");
Code__LocalVariables__add_internal_local_c("o2", "saved value of noun");
WRITE("switch (scope_stage) {\n"); INDENT;
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 {
Code__LocalVariables__add_internal_local_c("x", "saved value of noun");
WRITE("x=noun;\n");
WRITE("return ");
if (Specifications__get_proposition(nft->the_filter)) {
Calculus__Propositions__type_check(Specifications__get_proposition(nft->the_filter), Calculus__Propositions__tc_no_problem_reporting());
Calculus__Deferrals__compile_test_of_proposition(
OUT, noun_var, Specifications__get_proposition(nft->the_filter));
} else
Calculus__Deferrals__compile_test_if_var_matches_description(
OUT, noun_var, nft->the_filter);
WRITE(";\n");
}
OUT = Code__Routines__end(OUT);
Data__NonlocalVariables__set_kind(I6_noun_VAR, K);
}
#line 112 "inform7/Chapter 25/Noun Filter Tokens.w"
int too_late_for_further_NFTs = FALSE;
int Plugins__Parsing__Tokens__Filters__new_id(specification *spec, int global_scope) {
if (too_late_for_further_NFTs)
Problems__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__get_kind_referred_to(spec);
if ((Kinds__le(K, K_object) == FALSE) && (Kinds__request_I6_GPR(K) == FALSE))
Problems__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 nft_new(spec, global_scope)->allocation_id;
}
void Plugins__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=");
}
}
nft_compile_routine_name(OUT, nft);
}
}
#line 152 "inform7/Chapter 25/Noun Filter Tokens.w"
void Plugins__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;
nft_compile_routine(OUT, nft);
nft->nft_compiled = TRUE;
}
/* too_late_for_further_NFTs = TRUE; */
}
#line 19 "inform7/Chapter 25/Tokens Parsing Values.w"
void Plugins__Parsing__Tokens__Values__number(OUTPUT_STREAM) {
grammar_verb *gv = Kinds__get_parsing_grammar(K_number);
if (gv) Plugins__Parsing__Verbs__compile(OUT, gv);
}
void Plugins__Parsing__Tokens__Values__time(OUTPUT_STREAM) {
kind *K = Plugins__Times__kind();
if (K) {
grammar_verb *gv = Kinds__get_parsing_grammar(K);
if (gv) Plugins__Parsing__Verbs__compile(OUT, gv);
}
}
void Plugins__Parsing__Tokens__Values__truth_state(OUTPUT_STREAM) {
grammar_verb *gv = Kinds__get_parsing_grammar(K_truth_state);
if (gv) Plugins__Parsing__Verbs__compile(OUT, gv);
}
void Plugins__Parsing__Tokens__Values__compile_type_gprs(OUTPUT_STREAM) {
int k, next_label = 1, longest;
grammar_verb *gv;
kind *K;
LOOP_OVER_BASE_KINDS(K) {
if ((Kinds__is_an_enumeration(K)) ||
(Kinds__is_quasinumerical(K))) {
instance *q; literal_pattern *lp;
if (Kinds__needs_I6_GPR(K) == FALSE) continue;
OUT = Code__Routines__begin_numbered(OUT, "Kind_GPR_%d", Kinds__RuntimeIDs__weak(K));
Code__LocalVariables__add_internal_local("original_wn");
Code__LocalVariables__add_internal_local("group_wn");
Code__LocalVariables__add_internal_local("v");
Code__LocalVariables__add_internal_local("w");
Code__LocalVariables__add_internal_local("rv");
LITERAL_FORMS_LOOP(lp, K) {
Semantics__Nouns__LiteralPatterns__gpr_locals();
break;
}
{
#line 78 "inform7/Chapter 25/Tokens Parsing Values.w"
WRITE("original_wn = wn;\n");
LITERAL_FORMS_LOOP(lp, K) {
Semantics__Nouns__LiteralPatterns__gpr(OUT, lp);
WRITE("wn = original_wn;\n");
}
gv = Kinds__get_parsing_grammar(K);
if (gv != NULL) {
Plugins__Parsing__Verbs__compile(OUT, gv);
WRITE("wn = original_wn;\n");
}
longest = 0;
LOOP_OVER_INSTANCES(q, K) {
int nw1, nw2;
Data__Instances__get_name_in_play(q, &nw1, &nw2, FALSE);
if (nw2 - nw1 > longest) longest = nw2 - nw1;
}
for (; longest >= 0; longest--) {
LOOP_OVER_INSTANCES(q, K) {
int nw1, nw2;
Data__Instances__get_name_in_play(q, &nw1, &nw2, FALSE);
if (nw2 - nw1 == longest) {
if (GV_IS_VALUE_instance_mode) {
WRITE("if (instance == %s) {\n", Data__Instances__identifier(q)); INDENT;
}
WRITE("wn = original_wn;");
for (k=nw1; k<=nw2; k++) {
WRITE("if (NextWordStopped() ~= ");
Formats__Inform6__compile_dictionary_word(OUT, Text__word_text(k), FALSE);
WRITE(") jump Failed_%d;\n", next_label);
}
WRITE("parsed_number = %s; return GPR_NUMBER;\n",
Data__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 25/Tokens Parsing Values.w"
;
OUT = Code__Routines__end(OUT);
if (Kinds__is_an_enumeration(K)) {
OUT = Code__Routines__begin_numbered(OUT, "Instance_GPR_%d", Kinds__RuntimeIDs__weak(K));
Code__LocalVariables__add_named_call("instance");
Code__LocalVariables__add_internal_local("original_wn");
Code__LocalVariables__add_internal_local("group_wn");
Code__LocalVariables__add_internal_local("v");
Code__LocalVariables__add_internal_local("w");
Code__LocalVariables__add_internal_local("rv");
GV_IS_VALUE_instance_mode = TRUE;
{
#line 78 "inform7/Chapter 25/Tokens Parsing Values.w"
WRITE("original_wn = wn;\n");
LITERAL_FORMS_LOOP(lp, K) {
Semantics__Nouns__LiteralPatterns__gpr(OUT, lp);
WRITE("wn = original_wn;\n");
}
gv = Kinds__get_parsing_grammar(K);
if (gv != NULL) {
Plugins__Parsing__Verbs__compile(OUT, gv);
WRITE("wn = original_wn;\n");
}
longest = 0;
LOOP_OVER_INSTANCES(q, K) {
int nw1, nw2;
Data__Instances__get_name_in_play(q, &nw1, &nw2, FALSE);
if (nw2 - nw1 > longest) longest = nw2 - nw1;
}
for (; longest >= 0; longest--) {
LOOP_OVER_INSTANCES(q, K) {
int nw1, nw2;
Data__Instances__get_name_in_play(q, &nw1, &nw2, FALSE);
if (nw2 - nw1 == longest) {
if (GV_IS_VALUE_instance_mode) {
WRITE("if (instance == %s) {\n", Data__Instances__identifier(q)); INDENT;
}
WRITE("wn = original_wn;");
for (k=nw1; k<=nw2; k++) {
WRITE("if (NextWordStopped() ~= ");
Formats__Inform6__compile_dictionary_word(OUT, Text__word_text(k), FALSE);
WRITE(") jump Failed_%d;\n", next_label);
}
WRITE("parsed_number = %s; return GPR_NUMBER;\n",
Data__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 25/Tokens Parsing Values.w"
;
GV_IS_VALUE_instance_mode = FALSE;
OUT = Code__Routines__end(OUT);
}
}
}
}
#line 123 "inform7/Chapter 25/Tokens Parsing Values.w"
void Plugins__Parsing__Tokens__Values__gprv_compile(OUTPUT_STREAM, kind *K) {
WRITE("Kind_GPR_%d", Kinds__RuntimeIDs__weak(K));
}
void Plugins__Parsing__Tokens__Values__igprv_compile(OUTPUT_STREAM, kind *K) {
WRITE("Instance_GPR_%d", Kinds__RuntimeIDs__weak(K));
}
#line 27 "inform7/Chapter 25/General Parsing Routines.w"
STREAM *Plugins__Parsing__Tokens__General__compile_gpr_head(OUTPUT_STREAM, int id) {
OUT = Code__Routines__begin_numbered(OUT, "GPR_Line_%d", id);
Code__LocalVariables__add_internal_local_c("original_wn", "first word of text parsed");
Code__LocalVariables__add_internal_local_c("group_wn",
"first word matched against A/B/C/... disjunction");
Code__LocalVariables__add_internal_local_c("w", "for use by individual grammar lines");
Code__LocalVariables__add_internal_local_c("rv", "for use by individual grammar lines");
WRITE("original_wn = wn; rv = GPR_PREPOSITION;\n");
return OUT;
}
STREAM *Plugins__Parsing__Tokens__General__compile_gpr_tail(OUTPUT_STREAM) {
WRITE("return GPR_FAIL;\n");
OUT = Code__Routines__end(OUT);
return OUT;
}
STREAM *Plugins__Parsing__Tokens__General__compile_prn_pr_head(OUTPUT_STREAM, property *prn) {
OUT = Code__Routines__begin_numbered(OUT, "PRN_PN_%d", prn->allocation_id);
Code__LocalVariables__add_internal_local_c("original_wn", "first word of text parsed");
Code__LocalVariables__add_internal_local_c("group_wn",
"first word matched against A/B/C/... disjunction");
Code__LocalVariables__add_internal_local_c("w", "for use by individual grammar lines");
Code__LocalVariables__add_internal_local_c("rv", "for use by individual grammar lines");
WRITE("original_wn = wn; rv = GPR_PREPOSITION;\n");
return OUT;
}
STREAM *Plugins__Parsing__Tokens__General__compile_prn_pr_tail(OUTPUT_STREAM, property *prn) {
WRITE("return GPR_FAIL;\n");
OUT = Code__Routines__end(OUT);
return OUT;
}
#line 71 "inform7/Chapter 25/General Parsing Routines.w"
grammar_verb *consultation_gv = NULL; /* used only in routines below */
grammar_verb *Plugins__Parsing__Tokens__General__get_consultation_gv(void) {
if (consultation_gv == NULL) consultation_gv = Plugins__Parsing__Verbs__consultation_new();
return consultation_gv;
}
void Plugins__Parsing__Tokens__General__prepare_consultation_gv(void) {
consultation_gv = NULL;
}
int Plugins__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 25/General Parsing Routines.w"
STREAM *Plugins__Parsing__Tokens__General__compile_consult_head(OUTPUT_STREAM, int id) {
OUT = Code__Routines__begin_numbered(OUT, "Consult_Grammar_%d", id);
Code__LocalVariables__add_internal_local_c("range_from", "call parameter: word number of snippet start\n");
Code__LocalVariables__add_internal_local_c("range_words", "call parameter: snippet length\n");
Code__LocalVariables__add_internal_local_c("original_wn", "first word of text parsed\n");
Code__LocalVariables__add_internal_local_c("group_wn", "first word matched against A/B/C/... disjunction\n");
Code__LocalVariables__add_internal_local_c("w", "for use by individual grammar lines\n");
Code__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;
}
STREAM *Plugins__Parsing__Tokens__General__compile_consult_tail(OUTPUT_STREAM) {
WRITE("return GPR_FAIL;\n");
OUT = Code__Routines__end(OUT);
return OUT;
}
#line 132 "inform7/Chapter 25/General Parsing Routines.w"
STREAM *Plugins__Parsing__Tokens__General__compile_parse_name_property(inference_subject *subj) {
grammar_verb *gv = PF_S(parsing, subj)->understand_as_this_object;
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 (Plugins__Parsing__Verbs__is_empty(gv) == FALSE) {
STREAM_WRITE(PROP, "Parse_Name_GV%d", gv->allocation_id);
return PROP;
} else {
STREAM *XOUT = Plugins__Parsing__Tokens__General__compile_parse_name_head(PROP, subj, NULL);
if (XOUT) {
PROP = XOUT;
PROP = Plugins__Parsing__Tokens__General__compile_parse_name_tail(PROP);
STREAM_WRITE(PROP, ",");
return PROP;
}
}
STREAM_CLOSE(PROP);
return NULL;
}
#line 198 "inform7/Chapter 25/General Parsing Routines.w"
STREAM *Plugins__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 =
Plugins__Parsing__Visibility__any_property_visible_to_subject(subj, TRUE);
N = gv->allocation_id;
} else {
if (Plugins__Parsing__Visibility__any_property_visible_to_subject(subj, FALSE)
== FALSE) return NULL;
}
if (World__Subjects__domain(subj)) test_distinguishability = TRUE;
OUT = top_of_head(OUT, N, subj, test_distinguishability, sometimes_has_visible_properties);
return OUT;
}
#line 240 "inform7/Chapter 25/General Parsing Routines.w"
STREAM *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 = Code__Routines__begin(OUT, rname);
Code__LocalVariables__add_internal_local_c("original_wn", "first word of text parsed");
Code__LocalVariables__add_internal_local_c("group_wn", "first word matched against A/B/C/... disjunction");
Code__LocalVariables__add_internal_local_c("try_from_wn", "position to try matching from");
Code__LocalVariables__add_internal_local_c("n", "number of words matched");
Code__LocalVariables__add_internal_local_c("f", "flag: sufficiently good match found to justify success");
Code__LocalVariables__add_internal_local_c("w", "for use by individual grammar lines");
Code__LocalVariables__add_internal_local_c("rv", "for use by individual grammar lines");
Code__LocalVariables__add_internal_local_c("g", "temporary: success flag for parsing visibles");
Code__LocalVariables__add_internal_local_c("ss", "temporary: saves 'self' in distinguishing visibles");
Code__LocalVariables__add_internal_local_c("spn", "temporary: saves 'parsed_number' in parsing visibles");
Code__LocalVariables__add_internal_local_c("pass", "pass counter (1 to 3)");
Code__LocalVariables__add_internal_local_c("pass1_n", "value of n recorded during pass 1");
Code__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;
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 25/General Parsing Routines.w"
void Plugins__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 25/General Parsing Routines.w"
STREAM *Plugins__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 = Code__Routines__end(OUT);
return OUT;
}
#line 335 "inform7/Chapter 25/General Parsing Routines.w"
void 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;
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) && (Plugins__Parsing__Visibility__get_level(pp) > 0))
consider_visible_property(OUT, subj, pr, pp, phase);
}
finish_considering_visible_properties(OUT, phase);
}
}
#line 361 "inform7/Chapter 25/General Parsing Routines.w"
int visible_properties_code_written = FALSE; /* persistent state used only here */
void start_considering_visible_properties(OUTPUT_STREAM, int phase) {
visible_properties_code_written = FALSE;
}
void consider_visible_property(OUTPUT_STREAM, inference_subject *subj,
property *pr, property_permission *pp, int phase) {
int conditional_vis = FALSE;
specification *spec;
if (visible_properties_code_written == FALSE) {
visible_properties_code_written = TRUE;
if (phase == 1)
begin_distinguishing_visible_properties(OUT);
else
begin_parsing_visible_properties(OUT);
}
spec = Plugins__Parsing__Visibility__get_condition(pp);
if (spec) {
conditional_vis = TRUE;
TEMPORARY_STREAM;
Specifications__compile(TEMP, spec);
if (phase == 1)
test_distinguish_visible_property(OUT, TEMP);
else
test_parse_visible_property(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
if (phase == 1)
distinguish_visible_property(OUT, pr);
else
parse_visible_property(OUT, subj, pr, Plugins__Parsing__Visibility__get_level(pp));
if (conditional_vis) { OUTDENT; WRITE("}\n"); }
}
void finish_considering_visible_properties(OUTPUT_STREAM, int phase) {
if (visible_properties_code_written) {
if (phase == 1)
finish_distinguishing_visible_properties(OUT);
else
finish_parsing_visible_properties(OUT);
}
}
#line 420 "inform7/Chapter 25/General Parsing Routines.w"
void 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 test_distinguish_visible_property(OUTPUT_STREAM, 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 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__Implementation__OfObjects__compile_has_property(OUT, prn);
WRITE(") && (~~(parser_two "); Properties__Implementation__OfObjects__compile_has_property(OUT, prn);
WRITE("))) return -2;\n");
WRITE("if ((parser_two "); Properties__Implementation__OfObjects__compile_has_property(OUT, prn);
WRITE(") && (~~(parser_one "); Properties__Implementation__OfObjects__compile_has_property(OUT, prn);
WRITE("))) return -2;\n");
} else {
kind *K = Properties__Valued__kind(prn);
char *distinguisher = Kinds__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 finish_distinguishing_visible_properties(OUTPUT_STREAM) {
WRITE("self = ss; return 0;\n");
OUTDENT; WRITE("}\n");
}
#line 473 "inform7/Chapter 25/General Parsing Routines.w"
void 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 test_parse_visible_property(OUTPUT_STREAM, STREAM *COND) {
WRITE("if (");
STREAM_COPY(OUT, COND);
WRITE(") {\n"); INDENT;
}
int unique_pvp_counter = 0;
void 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;
parse_visible_either_or(OUT, prn, visibility_level, unique_pvp_counter);
prnbar = Properties__EitherOr__get_negation(prn);
if (prnbar)
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;
pvp_test_begins(OUT);
WRITE("spn = parsed_number; ss = etype; if ((");
recog_gpr = Kinds__get_recognition_only_GPR(K);
if (recog_gpr) {
WRITE("%s(self.%s) == GPR_PREPOSITION))",
recog_gpr, Properties__get_translation(prn));
} else if (Kinds__offers_I6_GPR(K)) {
char *i6_gpr_name = Kinds__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__is_an_enumeration(K)) {
Plugins__Parsing__Tokens__Values__igprv_compile(OUT, K);
WRITE("(self.%s) == GPR_NUMBER)) ", Properties__get_translation(prn));
} else {
Plugins__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");
pvp_test_passes(OUT, visibility_level, -1);
WRITE("parsed_number = spn; etype = ss;\n");
}
}
void parse_visible_either_or(OUTPUT_STREAM, property *prn, int visibility_level,
int pass_l) {
grammar_verb *gv = Properties__EitherOr__get_parsing_grammar(prn);
pvp_test_begins(OUT);
WRITE("if ((self ");
Properties__Implementation__OfObjects__compile_has_property(OUT, prn);
WRITE(") ");
pvp_test_words(OUT, prn->word_ref1, prn->word_ref2);
pvp_test_passes(OUT, visibility_level, pass_l);
if (gv) {
pvp_test_begins(OUT);
WRITE("if ((self ");
Properties__Implementation__OfObjects__compile_has_property(OUT, prn);
WRITE(") && (PRN_PN_%d() == GPR_PREPOSITION)) ", prn->allocation_id);
pvp_test_passes(OUT, visibility_level, pass_l);
}
}
void pvp_test_begins(OUTPUT_STREAM) {
WRITE("wn = try_from_wn; ");
}
void pvp_test_words(OUTPUT_STREAM, int w1, int w2) {
int i;
for (i=w1; i<=w2; i++) {
WRITE(" && ");
WRITE("(NextWordStopped()==");
Formats__Inform6__compile_dictionary_word(OUT, Text__word_text(i), FALSE);
WRITE(")");
}
WRITE(") ");
}
void 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 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 78 "inform7/Chapter 25/Test Scripts.w"
int test_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 210 "inform7/Chapter 25/Test Scripts.w"
*X = NO_INTT;
Problems__sentence_problem(_P_(C25UnknownInternalTest),
"that's an internal test case which I don't know",
"so I am taking no action.");
}
#line 80 "inform7/Chapter 25/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = EXTERNAL_INTT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 202 "inform7/Chapter 25/Test Scripts.w"
*X = FALSE;
Problems__sentence_problem(_P_(C25TestMultiWord),
"test scenarios must have single-word names",
"so 'test garden with ...' is allowed but not 'test garden gate with...'");
}
#line 82 "inform7/Chapter 25/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 83 "inform7/Chapter 25/Test Scripts.w"
#line 88 "inform7/Chapter 25/Test Scripts.w"
int internal_test_case_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 101 "inform7/Chapter 25/Test Scripts.w"
#line 105 "inform7/Chapter 25/Test Scripts.w"
test_scenario *ts_being_parsed = NULL;
#line 112 "inform7/Chapter 25/Test Scripts.w"
int test_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0: *X = TRUE;
{
#line 132 "inform7/Chapter 25/Test Scripts.w"
int i, j, k, x1 = R[1];
Text__dequote_word(x1);
char *p = Text__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;
check_test_command(individual_command);
} else individual_command[k++] = c;
ts_being_parsed->text_of_script[j++] = c;
if (j == MAX_LENGTH_OF_SCRIPT) {
LOG("Test script: %s\nLength: %d\n",
Text__word_raw_text(ts_being_parsed->commands_wn),
Platform__strlen(Text__word_raw_text(ts_being_parsed->commands_wn)));
Problems__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;
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 113 "inform7/Chapter 25/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
{
#line 132 "inform7/Chapter 25/Test Scripts.w"
int i, j, k, x1 = R[1];
Text__dequote_word(x1);
char *p = Text__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;
check_test_command(individual_command);
} else individual_command[k++] = c;
ts_being_parsed->text_of_script[j++] = c;
if (j == MAX_LENGTH_OF_SCRIPT) {
LOG("Test script: %s\nLength: %d\n",
Text__word_raw_text(ts_being_parsed->commands_wn),
Platform__strlen(Text__word_raw_text(ts_being_parsed->commands_wn)));
Problems__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;
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 114 "inform7/Chapter 25/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 194 "inform7/Chapter 25/Test Scripts.w"
Problems__sentence_problem(_P_(C25TestBadRequirements),
"I didn't recognise the requirements for this test scenario",
"which should be 'test ... with ... in ...' or '... "
"holding ...'");
}
#line 115 "inform7/Chapter 25/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 116 "inform7/Chapter 25/Test Scripts.w"
int test_case_circumstance_list_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 121 "inform7/Chapter 25/Test Scripts.w"
int test_case_circumstance_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
switch(R[0]) {
case 0:
{
#line 181 "inform7/Chapter 25/Test Scripts.w"
ts_being_parsed->place = RP[1];
}
#line 123 "inform7/Chapter 25/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 186 "inform7/Chapter 25/Test Scripts.w"
if (ts_being_parsed->no_possessions >= MAX_POSSESSIONS_PER_SCENARIO) {
{
#line 194 "inform7/Chapter 25/Test Scripts.w"
Problems__sentence_problem(_P_(C25TestBadRequirements),
"I didn't recognise the requirements for this test scenario",
"which should be 'test ... with ... in ...' or '... "
"holding ...'");
}
#line 187 "inform7/Chapter 25/Test Scripts.w"
;
} else
ts_being_parsed->possessions[ts_being_parsed->no_possessions++] = RP[1];
}
#line 124 "inform7/Chapter 25/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 194 "inform7/Chapter 25/Test Scripts.w"
Problems__sentence_problem(_P_(C25TestBadRequirements),
"I didn't recognise the requirements for this test scenario",
"which should be 'test ... with ... in ...' or '... "
"holding ...'");
}
#line 125 "inform7/Chapter 25/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 194 "inform7/Chapter 25/Test Scripts.w"
Problems__sentence_problem(_P_(C25TestBadRequirements),
"I didn't recognise the requirements for this test scenario",
"which should be 'test ... with ... in ...' or '... "
"holding ...'");
}
#line 126 "inform7/Chapter 25/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 218 "inform7/Chapter 25/Test Scripts.w"
Problems__sentence_problem(_P_(C25TestDoubleWith),
"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 127 "inform7/Chapter 25/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 128 "inform7/Chapter 25/Test Scripts.w"
#line 226 "inform7/Chapter 25/Test Scripts.w"
sentence_handler TEST_SH_handler =
{ SENTENCE_NT, TEST_VB, 2, new_test_text };
void new_test_text(parse_node *PN) {
int x1, x2;
x1 = PN->down->next->word_ref1; x2 = PN->down->next->word_ref2;
if (parse_nt_against_word_range(test_sentence_subject_NTM, x1, x2, NULL, NULL)) {
switch (most_recent_result) {
case NO_INTT: return;
case EXTERNAL_INTT:
{
#line 247 "inform7/Chapter 25/Test Scripts.w"
GET_RW(test_sentence_subject_NTM, 1, x1, x2);
test_scenario *test;
LOOP_OVER(test, test_scenario) {
if (compare_words(x1, test->name_wn)) {
Problems__quote_source(1, test->sentence_test_declared_at);
Problems__quote_source(2, current_sentence);
Problems__handmade_problem(_P_(C25TestDuplicate));
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_wn = x1;
test->sentence_test_declared_at = current_sentence;
test->place = NULL;
test->no_possessions = 0;
ts_being_parsed = test;
x1 = PN->down->next->next->word_ref1; x2 = PN->down->next->next->word_ref2;
parse_nt_against_word_range(test_sentence_object_NTM, x1, x2, NULL, NULL);
}
#line 235 "inform7/Chapter 25/Test Scripts.w"
; break;
default:
x1 = PN->down->next->next->word_ref1; x2 = PN->down->next->next->word_ref2;
new_internal_test_case(most_recent_result, x1, x2);
break;
}
}
}
#line 275 "inform7/Chapter 25/Test Scripts.w"
void check_test_command(char *p) {
if (strcmp(p, "undo") == 0) {
Problems__sentence_problem(_P_(C25TestContainsUndo),
"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__sentence_problem(_P_(C25TestCommandTooLong),
"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 Plugins__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("\"");
Formats__Inform6__compile_string(OUT, test->text_of_script,
ISN_EXPAND_APOSTROPHES + ISN_RECOGNISE_APOSTROPHE_SUBSTITUTION
+ ISN_FOR_ARRAY);
WRITE("||||\";\n");
OUTDENT;
WRITE("Array TestReq_%d -->\n", test->allocation_id); INDENT;
if (test->place == NULL) WRITE("0 ");
else WRITE("%s ", Data__Instances__identifier(test->place));
for (j=0; j<test->no_possessions; j++) {
if (test->possessions[j] == NULL) WRITE("0 ");
else WRITE("%s ", Data__Instances__identifier(test->possessions[j]));
}
WRITE("0;\n");
OUTDENT;
}
}
void Plugins__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",
Text__word_raw_text(test->name_wn),
test->allocation_id, test->allocation_id, l);
}
}
void Plugins__Parsing__TestScripts__compile_printout(OUTPUT_STREAM) {
test_scenario *test;
LOOP_OVER(test, test_scenario)
WRITE("print \"'test %s'^\";\n",
Text__word_raw_text(test->name_wn));
}
#line 342 "inform7/Chapter 25/Test Scripts.w"
void new_internal_test_case(int code, int x1, int x2) {
internal_test_case *itc = CREATE(internal_test_case);
itc->itc_code = code; itc->word_ref1 = x1; itc->word_ref2 = x2;
itc->itc_defined_at = current_sentence;
}
STREAM *itc_save_dl = NULL, *itc_save_OUT = NULL;
void Plugins__Parsing__TestScripts__InternalTestCases_routine(OUTPUT_STREAM) {
internal_test_case *itc; int n = 0;
OUT = Code__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 \"^");
Text__print_raw_text_to_stream(itc->word_ref1, itc->word_ref2, OUT);
WRITE("^\"; style roman;\n");
continue;
}
WRITE("print \"%d. ", n);
if (itc->itc_code == ARTICLE_INTT) {
Text__dequote_word(itc->word_ref1);
WRITE("%s", Text__word_text(itc->word_ref1));
} else {
Text__print_raw_text_to_stream(itc->word_ref1, itc->word_ref2, OUT);
}
WRITE("^\";\n");
WRITE("print \"");
current_sentence = itc->itc_defined_at;
switch (itc->itc_code) {
case SENTENCE_INTT: {
unsigned int required_S_form = SV_ML;
{
#line 485 "inform7/Chapter 25/Test Scripts.w"
meaning_list *ml = NULL;
pcalc_prop *prop = NULL;
int tc = FALSE;
if (required_S_form == SV_ML) {
if (parse_nt_against_word_range(s_condition_pure_NTM, itc->word_ref1, itc->word_ref2, NULL, NULL)) ml = most_recent_result_p;
} else {
if (parse_nt_against_word_range(s_condition_NTM, itc->word_ref1, itc->word_ref2, NULL, NULL)) ml = most_recent_result_p;
}
if ((ml) && (Parser__SP__MeaningLists__production(ml) == COND_ML) &&
(Parser__SP__MeaningLists__down(ml)) && (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml)) == required_S_form)) {
prop = Parser__SP__Conversion__S_subtree(Parser__SP__MeaningLists__down(ml), NULL);
tc = Calculus__Propositions__type_check(prop, Calculus__Propositions__tc_no_problem_reporting());
}
{
#line 516 "inform7/Chapter 25/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 500 "inform7/Chapter 25/Test Scripts.w"
;
if (ml == NULL) LOG("Failed: not a condition");
else if (Parser__SP__MeaningLists__production(ml) != COND_ML) LOG("Failed: tree head is $p", Parser__SP__MeaningLists__production(ml));
else if (Parser__SP__MeaningLists__down(ml) == NULL) LOG("Failed: treeless COND");
else if (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml)) != required_S_form)
LOG("Failed: not SV but $p", Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml)));
else {
LOG("$D\n", prop);
if (tc == FALSE) LOG("Failed: proposition would not type-check\n");
Calculus__Propositions__type_check(prop, Calculus__Propositions__tc_problem_logging());
}
{
#line 521 "inform7/Chapter 25/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 511 "inform7/Chapter 25/Test Scripts.w"
;
}
#line 376 "inform7/Chapter 25/Test Scripts.w"
;
break;
}
case DESCRIPTION_INTT: {
unsigned int required_S_form = SN_ML;
{
#line 485 "inform7/Chapter 25/Test Scripts.w"
meaning_list *ml = NULL;
pcalc_prop *prop = NULL;
int tc = FALSE;
if (required_S_form == SV_ML) {
if (parse_nt_against_word_range(s_condition_pure_NTM, itc->word_ref1, itc->word_ref2, NULL, NULL)) ml = most_recent_result_p;
} else {
if (parse_nt_against_word_range(s_condition_NTM, itc->word_ref1, itc->word_ref2, NULL, NULL)) ml = most_recent_result_p;
}
if ((ml) && (Parser__SP__MeaningLists__production(ml) == COND_ML) &&
(Parser__SP__MeaningLists__down(ml)) && (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml)) == required_S_form)) {
prop = Parser__SP__Conversion__S_subtree(Parser__SP__MeaningLists__down(ml), NULL);
tc = Calculus__Propositions__type_check(prop, Calculus__Propositions__tc_no_problem_reporting());
}
{
#line 516 "inform7/Chapter 25/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 500 "inform7/Chapter 25/Test Scripts.w"
;
if (ml == NULL) LOG("Failed: not a condition");
else if (Parser__SP__MeaningLists__production(ml) != COND_ML) LOG("Failed: tree head is $p", Parser__SP__MeaningLists__production(ml));
else if (Parser__SP__MeaningLists__down(ml) == NULL) LOG("Failed: treeless COND");
else if (Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml)) != required_S_form)
LOG("Failed: not SV but $p", Parser__SP__MeaningLists__production(Parser__SP__MeaningLists__down(ml)));
else {
LOG("$D\n", prop);
if (tc == FALSE) LOG("Failed: proposition would not type-check\n");
Calculus__Propositions__type_check(prop, Calculus__Propositions__tc_problem_logging());
}
{
#line 521 "inform7/Chapter 25/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 511 "inform7/Chapter 25/Test Scripts.w"
;
}
#line 381 "inform7/Chapter 25/Test Scripts.w"
;
break;
}
case EVALUATION_INTT: {
specification *spec = NULL;
if (parse_nt_against_word_range(spec_value_NTM, itc->word_ref1, itc->word_ref2, NULL, NULL)) spec = most_recent_result_p;
else spec = Specifications__Unknown__new(itc->word_ref1, itc->word_ref2);
Specifications__Matching__check_without_expectations(spec);
kind *K = Specifications__evaluates_to(spec);
WRITE("Kind of value: ");
{
#line 516 "inform7/Chapter 25/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 391 "inform7/Chapter 25/Test Scripts.w"
;
Kinds__log(K);
if (Kinds__is_quasinumerical(K)) LOG(" scaled at k=%d", Kinds__scale_factor(K));
{
#line 521 "inform7/Chapter 25/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 394 "inform7/Chapter 25/Test Scripts.w"
;
WRITE("^Prints as: \", (%s) ",
Kinds__get_name_of_printing_rule(K));
TEMPORARY_STREAM;
Specifications__compile(TEMP, spec);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
WRITE(", \"^");
break;
}
case DIMENSIONS_INTT:
{
#line 516 "inform7/Chapter 25/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 405 "inform7/Chapter 25/Test Scripts.w"
;
Kinds__Dimensions__log_unit_analysis();
{
#line 521 "inform7/Chapter 25/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 407 "inform7/Chapter 25/Test Scripts.w"
;
break;
case EQUATION_INTT:
Data__Equations__internal_test(itc->word_ref1, itc->word_ref2);
break;
case ARTICLE_INTT:
Text__Inflections__test_tries(OUT, Text__word_text(itc->word_ref1));
break;
case VERB_INTT:
Semantics__test_conjugation(OUT, itc->word_ref1, itc->word_ref2);
break;
case ADJECTIVE_INTT:
Semantics__Adjectives__Meanings__test_adjective(OUT, itc->word_ref1, itc->word_ref2);
break;
case ING_INTT:
Semantics__test_participle(OUT, itc->word_ref1, itc->word_ref2);
break;
case KIND_INTT:
{
#line 516 "inform7/Chapter 25/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 425 "inform7/Chapter 25/Test Scripts.w"
;
Kinds__log_poset(Text__Vocabulary__get_literal_number_value(Text__word(itc->word_ref1)));
{
#line 521 "inform7/Chapter 25/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 427 "inform7/Chapter 25/Test Scripts.w"
;
break;
case MAP_INTT:
{
#line 516 "inform7/Chapter 25/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 430 "inform7/Chapter 25/Test Scripts.w"
;
Plugins__Map__log_spatial_layout();
{
#line 521 "inform7/Chapter 25/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 432 "inform7/Chapter 25/Test Scripts.w"
;
break;
}
WRITE("^\";\n");
}
OUT = Code__Routines__end(OUT);
}
void Plugins__Parsing__TestScripts__Internal__begin_reporting(void) {
{
#line 516 "inform7/Chapter 25/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 441 "inform7/Chapter 25/Test Scripts.w"
;
}
void Plugins__Parsing__TestScripts__Internal__end_reporting(void) {
{
#line 521 "inform7/Chapter 25/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 445 "inform7/Chapter 25/Test Scripts.w"
;
}
void Plugins__Parsing__TestScripts__Internal__showme(OUTPUT_STREAM, specification *spec) {
itc_save_OUT = OUT;
if (Specifications__species_is(spec, PROPERTY_VALUE_SPC))
spec = Specifications__Storage__underlying_property(spec);
kind *K = Specifications__evaluates_to(spec);
if (Specifications__Values__is_actual_CONSTANT(spec) == FALSE) {
WRITE("~");
Text__print_raw_text_within_i6_literal(OUT, spec->word_ref1, spec->word_ref2);
WRITE("~ = ");
}
{
#line 516 "inform7/Chapter 25/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 458 "inform7/Chapter 25/Test Scripts.w"
;
Kinds__log(K);
{
#line 521 "inform7/Chapter 25/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 460 "inform7/Chapter 25/Test Scripts.w"
;
if (Kinds__get_construct(K) == CON_list_of) {
WRITE(": \"; LIST_OF_TY_Say(");
TEMPORARY_STREAM;
Specifications__compile(TEMP, spec);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
WRITE(", 1); print \"");
} else {
WRITE(": \", (%s) ",
Kinds__get_name_of_printing_rule(K));
TEMPORARY_STREAM;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__compile(TEMP, spec);
END_COMPILATION_MODE;
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
WRITE(", \"");
}
}
#line 45 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_INSTANCE_NOTIFY, figures_new_named_instance_notify);
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, figures_new_base_kind_notify);
}
#line 53 "inform7/Chapter 26/Figures.w"
int figures_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) {
if ((name) && (strcmp(name, "FIGURE_NAME_TY") == 0)) {
K_figure_name = new_base; return TRUE;
}
return FALSE;
}
int allow_figure_creations = FALSE;
int figures_new_named_instance_notify(instance *nc) {
if (K_figure_name == NULL) return FALSE;
kind *K = Data__Instances__kind(nc);
if (Kinds__eq(K, K_figure_name)) {
if (allow_figure_creations == FALSE)
Problems__sentence_problem(_P_(C26BackdoorFigureCreation),
"this is not the way to create a new figure name",
"which should be done with a special 'Figure ... is the file ...' "
"sentence.");
Data__Instances__set_connection(nc,
STORE_POINTER_blorb_figure(new_blorb_figure(nc)));
return TRUE;
}
return FALSE;
}
blorb_figure *new_blorb_figure(instance *nc) {
blorb_figure *bf = CREATE(blorb_figure);
bf->word_ref1 = -1; bf->word_ref2 = -1;
bf->path_to_figure[0] = 0;
bf->figure_number = 0;
bf->alt_description = -1;
return bf;
}
#line 90 "inform7/Chapter 26/Figures.w"
sentence_handler FIGURE_SH_handler =
{ SENTENCE_NT, FIGURE_VB, 1, handle_figure_definition };
void handle_figure_definition(parse_node *p) {
if (Config__Plugins__plugged_in(figures_plugin) == FALSE)
internal_error("Figures plugin inactive");
register_figure(p->down->next->word_ref1,
p->down->next->word_ref2,
p->down->next->next->word_ref1,
p->down->next->next->word_ref2);
}
#line 105 "inform7/Chapter 26/Figures.w"
int figure_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 108 "inform7/Chapter 26/Figures.w"
int figure_source_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 117 "inform7/Chapter 26/Figures.w"
Problems__sentence_problem(_P_(C26PictureNotTextual),
"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 112 "inform7/Chapter 26/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 113 "inform7/Chapter 26/Figures.w"
#line 129 "inform7/Chapter 26/Figures.w"
int notable_figures_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 131 "inform7/Chapter 26/Figures.w"
#line 135 "inform7/Chapter 26/Figures.w"
void register_figure(int f1, int f2, int fn1, int fn2) {
alttext_NTMV = -1;
parse_nt_against_word_range(figure_sentence_object_NTM, fn1, fn2, 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);
Parser__Assertions__vet_name_for_noun(f1, f2);
if ((parse_nt_against_word_range(spec_value_NTM, f1, f2, NULL, NULL)) &&
(Specifications__Values__is_actual_CONSTANT_of_kind(most_recent_result_p, K_figure_name))) {
Problems__sentence_problem(_P_(C26PictureDuplicate),
"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__to_create_something(K_figure_name, f1, f2);
Calculus__Propositions__assert_true(prop, CERTAIN_CE);
allow_figure_creations = FALSE;
blorb_figure *bf = RETRIEVE_POINTER_blorb_figure(
Data__Instances__get_connection(latest_instance));
bf->word_ref1 = f1; bf->word_ref2 = f2;
if (wn >= 0) {
bf->figure_number = Code__VirtualMachines__get_next_free_blorb_resource_ID();
sprintf(bf->path_to_figure, "Figures%c%s", FOLDER_SEPARATOR, Text__word_text(wn));
bf->alt_description = alttext_NTMV;
} else {
bf->figure_number = 1;
bf->path_to_figure[0] = 0;
bf->alt_description = alttext_NTMV;
F_cover_art = bf;
}
LOGIF(FIGURE_CREATIONS, "Created figure <$W> = filename '%s' = resource ID %d\n",
f1, f2, (wn>=0)?Text__word_text(wn):"<cover art>", bf->figure_number);
}
char *Plugins__Figures__description_of_cover_art(void) {
if ((F_cover_art == NULL) || (F_cover_art->alt_description == -1)) return "";
return Text__word_text(F_cover_art->alt_description);
}
#line 185 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__write_picture_manifest(OUTPUT_STREAM, int releasing_cover) {
if (Config__Plugins__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 (releasing_cover) {
WRITE("<key>1</key>\n");
WRITE("<string>Cover.jpg</string>\n");
}
LOOP_OVER(bf, blorb_figure)
if (bf->figure_number > 1) {
WRITE("<key>%d</key>\n", bf->figure_number);
WRITE("<string>%s</string>\n", bf->path_to_figure);
}
OUTDENT; WRITE("</dict>\n");
Plugins__Sounds__write_sounds_manifest(OUT);
OUTDENT; WRITE("</dict>\n");
OUTDENT; WRITE("</plist>\n");
}
#line 214 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__write_blurb_commands(OUTPUT_STREAM, char *resources) {
if (Config__Plugins__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 = Text__word_text(bf->alt_description);
if (strlen(desc) > 0)
WRITE("picture %d \"%s%c%s\" \"%s\"\n",
bf->figure_number, resources,
FOLDER_SEPARATOR, bf->path_to_figure,
desc);
else
WRITE("picture %d \"%s%c%s\"\n",
bf->figure_number, resources,
FOLDER_SEPARATOR, bf->path_to_figure);
}
}
#line 237 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__write_copy_commands(void) {
if (Config__Plugins__plugged_in(figures_plugin) == FALSE) return;
blorb_figure *bf;
LOOP_OVER(bf, blorb_figure)
if (bf->figure_number > 1)
Plugins__Bibliographic__create_aux_file(bf->path_to_figure,
"--", "Figures", SEPARATE_FIGURES_PAYLOAD);
}
#line 249 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__tableoffigures_array(OUTPUT_STREAM) {
if (Config__Plugins__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 265 "inform7/Chapter 26/Figures.w"
void Plugins__Figures__index_all(void) {
if (Config__Plugins__plugged_in(figures_plugin) == FALSE) return;
blorb_figure *bf; FILE *FIGURE_FILE;
char image_filename[MAX_FILENAME_LENGTH];
char line2[MAX_FILENAME_LENGTH];
int MAX_INDEXED_FIGURES = Config__Inclusions__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");
Formats__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;
sprintf(image_filename, "%s%c%s", materials_folder, FOLDER_SEPARATOR,
bf->path_to_figure);
rv = 0;
FIGURE_FILE = Platform__iso_fopen(image_filename, "rb");
if (FIGURE_FILE) {
char *real_format = "JPEG";
rv = Files__Formats__JPEG__get_dimensions(FIGURE_FILE, &width, &height);
fclose(FIGURE_FILE);
if (rv == 0) {
FIGURE_FILE = Platform__iso_fopen(image_filename, "rb");
if (FIGURE_FILE) {
real_format = "PNG";
rv = Files__Formats__PNG__get_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 .materials%cFigures folder</i><br>\n",
FOLDER_SEPARATOR);
}
Formats__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)
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);
Formats__HTML__next_html_column(ifl, 0);
Text__print_raw_text_to_stream(bf->word_ref1, bf->word_ref2, ifl);
Index__link(bf->word_ref1);
INDEX("<br>\n%sFilename: \"%s\" - resource number %d",
line2, bf->path_to_figure, bf->figure_number);
Formats__HTML__end_html_row(ifl);
}
}
Formats__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 26/Sound Effects.w"
void Plugins__Sounds__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_INSTANCE_NOTIFY, sounds_new_named_instance_notify);
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, sounds_new_base_kind_notify);
}
#line 49 "inform7/Chapter 26/Sound Effects.w"
int sounds_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) {
if ((name) && (strcmp(name, "SOUND_NAME_TY") == 0)) {
K_sound_name = new_base; return TRUE;
}
return FALSE;
}
int allow_sound_creations = FALSE;
int sounds_new_named_instance_notify(instance *nc) {
if (K_sound_name == NULL) return FALSE;
kind *K = Data__Instances__kind(nc);
if (Kinds__eq(K, K_sound_name)) {
if (allow_sound_creations == FALSE)
Problems__sentence_problem(_P_(C26BackdoorSoundCreation),
"this is not the way to create a new sound name",
"which should be done with a special 'Sound ... is the file ...' "
"sentence.");
Data__Instances__set_connection(nc,
STORE_POINTER_blorb_sound(new_blorb_sound(nc)));
return TRUE;
}
return FALSE;
}
blorb_sound *new_blorb_sound(instance *nc) {
blorb_sound *bs = CREATE(blorb_sound);
return bs;
}
#line 82 "inform7/Chapter 26/Sound Effects.w"
sentence_handler SOUND_SH_handler =
{ SENTENCE_NT, SOUND_VB, 1, handle_sound_definition };
void handle_sound_definition(parse_node *p) {
if (Config__Plugins__plugged_in(sounds_plugin) == FALSE)
internal_error("Sounds plugin inactive");
register_sound(p->down->next->word_ref1,
p->down->next->word_ref2,
p->down->next->next->word_ref1,
p->down->next->next->word_ref2);
}
#line 97 "inform7/Chapter 26/Sound Effects.w"
int sound_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 100 "inform7/Chapter 26/Sound Effects.w"
int sound_source_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 108 "inform7/Chapter 26/Sound Effects.w"
Problems__sentence_problem(_P_(C26SoundNotTextual),
"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 103 "inform7/Chapter 26/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 104 "inform7/Chapter 26/Sound Effects.w"
#line 118 "inform7/Chapter 26/Sound Effects.w"
void register_sound(int f1, int f2, int fn1, int fn2) {
alttext_NTMV = -1;
parse_nt_against_word_range(sound_sentence_object_NTM, fn1, fn2, 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);
Parser__Assertions__vet_name_for_noun(f1, f2);
if ((parse_nt_against_word_range(spec_value_NTM, f1, f2, NULL, NULL)) &&
(Specifications__Values__is_actual_CONSTANT_of_kind(most_recent_result_p, K_sound_name))) {
Problems__sentence_problem(_P_(C26SoundDuplicate),
"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__to_create_something(
K_sound_name, f1, f2);
Calculus__Propositions__assert_true(prop, CERTAIN_CE);
allow_sound_creations = FALSE;
blorb_sound *bs = RETRIEVE_POINTER_blorb_sound(
Data__Instances__get_connection(latest_instance));
sprintf(bs->path_to_sound, "Sounds%c%s", FOLDER_SEPARATOR, Text__word_text(wn));
bs->word_ref1 = f1; bs->word_ref2 = f2;
bs->sound_number = Code__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",
f1, f2, Text__word_text(wn), bs->sound_number);
}
#line 161 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__write_sounds_manifest(OUTPUT_STREAM) {
if (Config__Plugins__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);
WRITE("<string>%s</string>\n", bs->path_to_sound);
}
OUTDENT; WRITE("</dict>\n");
}
#line 177 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__write_blurb_commands(OUTPUT_STREAM, char *resources) {
if (Config__Plugins__plugged_in(sounds_plugin) == FALSE) return;
blorb_sound *bs;
LOOP_OVER(bs, blorb_sound) {
char *desc = "";
if (bs->alt_description >= 0)
desc = Text__word_text(bs->alt_description);
if (strlen(desc) > 0)
WRITE("sound %d \"%s%c%s\" \"%s\"\n",
bs->sound_number, resources, FOLDER_SEPARATOR, bs->path_to_sound,
desc);
else
WRITE("sound %d \"%s%c%s\"\n",
bs->sound_number, resources, FOLDER_SEPARATOR, bs->path_to_sound);
}
}
#line 197 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__write_copy_commands(void) {
if (Config__Plugins__plugged_in(sounds_plugin) == FALSE) return;
blorb_sound *bs;
LOOP_OVER(bs, blorb_sound)
Plugins__Bibliographic__create_aux_file(bs->path_to_sound, "--", "Sounds",
SEPARATE_SOUNDS_PAYLOAD);
}
#line 208 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__tableofsounds_array(OUTPUT_STREAM) {
if (Config__Plugins__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 220 "inform7/Chapter 26/Sound Effects.w"
void Plugins__Sounds__index_all(void) {
if (Config__Plugins__plugged_in(sounds_plugin) == FALSE) return;
blorb_sound *bs; FILE *SOUND_FILE;
char image_filename[MAX_FILENAME_LENGTH];
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");
Formats__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;
sprintf(image_filename, "%s%c%s", materials_folder, FOLDER_SEPARATOR, bs->path_to_sound);
rv = 0;
SOUND_FILE = Platform__iso_fopen(image_filename, "rb");
if (SOUND_FILE) {
char *real_format = "AIFF";
rv = Files__Formats__AIFF__get_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(image_filename, "rb");
if (SOUND_FILE) {
real_format = "Ogg Vorbis";
preview = FALSE;
rv = Files__Formats__OggVorbis__get_duration(SOUND_FILE, &duration, &pBitsPerSecond,
&pChannels, &pSampleRate);
fclose(SOUND_FILE);
}
}
if (rv == 0) {
SOUND_FILE = Platform__iso_fopen(image_filename, "rb");
if (SOUND_FILE) {
waveform_style = FALSE;
real_format = "MIDI";
preview = TRUE;
rv = Files__Formats__Midi__get_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 .materials%cSounds folder</i><br>\n",
FOLDER_SEPARATOR);
}
Formats__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)
INDEX("<embed src=\"file://%s\" width=\"%d\" height=\"64\" "
"autostart=\"false\" volume=\"50%%\" mastersound></embed>&nbsp;",
image_filename, THUMBNAIL_WIDTH);
else
INDEX("<img border=\"0\" src=\"inform:/doc_images/sound_okay.png\">&nbsp;");
}
Formats__HTML__next_html_column(ifl, 0);
Text__print_raw_text_to_stream(bs->word_ref1, bs->word_ref2, ifl);
Index__link(bs->word_ref1);
INDEX("<br>\n%sFilename: \"%s\" - resource number %d",
line2, bs->path_to_sound, bs->sound_number);
Formats__HTML__end_html_row(ifl);
}
Formats__HTML__end_html_table(ifl);
INDEX("<p>");
}
#line 43 "inform7/Chapter 26/External Files.w"
void Plugins__Files__start(void) {
PLUGIN_REGISTER(PLUGIN_COMPILE_CONSTANT, files_compile_constant);
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, files_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_NEW_INSTANCE_NOTIFY, files_new_named_instance_notify);
}
#line 52 "inform7/Chapter 26/External Files.w"
int files_new_base_kind_notify(kind *new_base, char *name, int w1, int w2) {
if ((name) && (strcmp(name, "EXTERNAL_FILE_TY") == 0)) {
K_external_file = new_base; return TRUE;
}
return FALSE;
}
int allow_exf_creations = FALSE;
int files_new_named_instance_notify(instance *nc) {
if (K_external_file == NULL) return FALSE;
kind *K = Data__Instances__kind(nc);
if (Kinds__eq(K, K_external_file)) {
if (allow_exf_creations == FALSE)
Problems__sentence_problem(_P_(C26BackdoorFileCreation),
"this is not the way to create a new external file",
"which should be done with a special 'The File ... is called ...' "
"sentence.");
Data__Instances__set_connection(nc,
STORE_POINTER_external_file(new_external_file(nc)));
return TRUE;
}
return FALSE;
}
#line 79 "inform7/Chapter 26/External Files.w"
external_file *new_external_file(instance *nc) {
external_file *exf = CREATE(external_file);
return exf;
}
#line 91 "inform7/Chapter 26/External Files.w"
int external_file_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 26/External Files.w"
int external_file_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 26/External Files.w"
int external_file_owner_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 26/External Files.w"
*X = NOT_APPLICABLE;
Problems__sentence_problem(_P_(C26BadFileOwner),
"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 26/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 26/External Files.w"
#line 127 "inform7/Chapter 26/External Files.w"
int external_file_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 26/External Files.w"
*X = -1;
Problems__sentence_problem(_P_(C26FilenameNotTextual),
"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 26/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 26/External Files.w"
#line 142 "inform7/Chapter 26/External Files.w"
sentence_handler FILE_SH_handler =
{ SENTENCE_NT, FILE_VB, 1, handle_file_definition };
void handle_file_definition(parse_node *p) {
if (Config__Plugins__plugged_in(files_plugin) == FALSE)
internal_error("Files plugin inactive");
register_file(p->down->next->word_ref1,
p->down->next->word_ref2,
p->down->next->next->word_ref1,
p->down->next->next->word_ref2);
}
void register_file(int f1, int f2, int fn1, int fn2) {
char *p; int i;
int bad_filename = FALSE;
parse_nt_against_word_range(external_file_sentence_object_NTM, fn1, fn2, NULL, NULL);
fn1 = most_recent_result;
if (fn1 < 0) return;
p = Text__word_text(fn1);
if (Platform__strlen(p) < 5) bad_filename = TRUE;
if (isalpha(p[1]) == FALSE) bad_filename = TRUE;
for (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__sentence_problem(_P_(C26FilenameUnsafe),
"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 (parse_nt_against_word_range(external_file_sentence_subject_NTM, f1, f2, NULL, NULL) == FALSE) internal_error("bad ef grammar");
GET_RW(external_file_name_NTM, 1, f1, f2);
int binary = most_recent_result;
if (ownership_NTMV == TRUE) {
int own2;
GET_RW(external_file_owner_NTM, 1, own2, own2);
int j, invalid = FALSE;
p = Text__word_text(own2);
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__sentence_problem(_P_(C26BadFileIFID),
"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;
}
Parser__Assertions__vet_name_for_noun(f1, f2);
if ((parse_nt_against_word_range(spec_value_NTM, f1, f2, NULL, NULL)) &&
(Specifications__Values__is_actual_CONSTANT_of_kind(most_recent_result_p, K_external_file))) {
Problems__sentence_problem(_P_(C26FilenameDuplicate),
"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__to_create_something(
K_external_file, f1, f2);
Calculus__Propositions__assert_true(prop, CERTAIN_CE);
allow_exf_creations = FALSE;
external_file *exf = RETRIEVE_POINTER_external_file(
Data__Instances__get_connection(latest_instance));
exf->word_ref1 = f1; exf->word_ref2 = f2;
exf->unextended_filename = fn1;
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",
f1, f2, Text__word_text(exf->unextended_filename));
Formats__Inform6__compose_identifier(exf->exf_I6_identifier, 'X', exf->allocation_id,
exf->word_ref1, exf->word_ref2);
}
#line 251 "inform7/Chapter 26/External Files.w"
int files_compile_constant(OUTPUT_STREAM, kind *K, specification *spec) {
if (Config__Plugins__plugged_in(files_plugin) == FALSE)
internal_error("files plugin inactive");
if ((Kinds__eq(K, K_external_file)) && (parse_nt_against_word_range(literal_NTM, spec->word_ref1, spec->word_ref2, NULL, NULL))) {
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 269 "inform7/Chapter 26/External Files.w"
void Plugins__Files__arrays(OUTPUT_STREAM) {
if (Config__Plugins__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 ", Text__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 303 "inform7/Chapter 26/External Files.w"
void Plugins__Files__index_all(void) {
if (Config__Plugins__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");
Formats__HTML__begin_html_table(ifl, "#ffffff", TRUE, 0, 0, 0, 0, 0);
LOOP_OVER(exf, external_file) {
Formats__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;");
}
Formats__HTML__next_html_column(ifl, 0);
Text__print_raw_text_to_stream(exf->word_ref1, exf->word_ref2, ifl);
Index__link(exf->word_ref1);
INDEX("<br>\nFilename: %s %s- owned by ",
(exf->file_is_binary)?"- binary ":"",
Text__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;
}
Formats__HTML__end_html_row(ifl);
}
Formats__HTML__end_html_table(ifl);
INDEX("<p>");
}
#line 31 "inform7/Chapter 27/Main Routine.w"
int main(int argc, char *argv[]) {
clock_t start = clock();
int i, a = 1, source_specified = FALSE, report_clock_time = FALSE;
char *val;
STREAM_WRITE(STDOUT, "%s build %s has started.\n", NI_VERSION, NI_BUILD);
STREAM_FLUSH(STDOUT);
what_day_is_it();
bundle_name = NULL;
crash_on_internal_errors = FALSE;
crash_on_all_errors = FALSE;
story_filename_extension = NULL;
Files__Filenames__make_pathname_of_extensions();
if (argc == a) return 0;
while (a < argc) {
char *option = argv[a];
if ((option[0] == '-') && (option[1] == '-')) option++;
if (strcmp("-log", option) == 0) {
/* Non-functional for now */
a++; continue;
}
if (Platform__strlen(option) > 5) {
if ((option[0] == '-') && (option[1] == 'l') && (option[2] == 'o') &&
(option[3] == 'g') && (option[4] == '=')) {
Log__Aspects__set_from_command_line(option+5);
a++; continue;
}
}
if (strcmp("-rng", option) == 0) {
fix_rng_at_start_of_play = TRUE;
rng_seed_at_start_of_play = -16339;
a++; continue;
}
if ((val = cli_pair("-extension", option)) != 0) {
story_filename_extension = val;
a++; continue;
}
if (strcmp("-release", option) == 0) {
this_is_a_release_compile = TRUE;
a++; continue;
}
if (strcmp("-noprogress", option) == 0) {
show_progress_indicator = FALSE;
a++; continue;
}
if (strcmp("-census", option) == 0) {
census_mode = TRUE;
a++; continue;
}
if (strcmp("-clock", option) == 0) {
report_clock_time = TRUE;
a++; continue;
}
if (strcmp("-sigils", option) == 0) {
echo_problem_message_sigils = TRUE;
a++; continue;
}
if (strcmp("-gdb", option) == 0) {
crash_on_internal_errors = TRUE;
a++; continue;
}
if (strcmp("-gdball", option) == 0) {
crash_on_all_errors = TRUE;
a++; continue;
}
if (strcmp("-noindex", option) == 0) {
do_not_generate_index = TRUE;
a++; continue;
}
if (strcmp("-package", option) == 0) {
source_specified = TRUE;
Platform__truncated_locale_arg(argv[a+1],
pathname_of_bundle, MAX_FILENAME_LENGTH);
bundle_name = pathname_of_bundle;
a = a+2; continue;
}
if (strcmp("-extensions", option) == 0) {
Platform__truncated_locale_arg(argv[a+1],
pathname_of_extensions, MAX_FILENAME_LENGTH);
a = a+2; continue;
}
if (strcmp("-rules", option) == 0) {
Platform__truncated_locale_arg(argv[a+1],
pathname_of_built_in_extensions, MAX_FILENAME_LENGTH);
a = a+2; continue;
}
if (strcmp("-scoring", option) == 0) {
default_scoring_setting = TRUE;
a++; continue;
}
if (source_specified) {
Problems__Fatal__issue("Unknown parameter at the command line");
} else {
source_specified = TRUE;
source_text_file = argv[a]; a++;
}
}
Files__Filenames__make_pathname_of_materials_folder();
Code__VirtualMachines__set_identifier(story_filename_extension);
if ((census_mode == FALSE) && (source_specified == FALSE))
Problems__Fatal__issue("Except in census mode, source text must be supplied");
if ((census_mode) && (source_specified))
Problems__Fatal__issue("In census mode, no source text may be supplied");
Log__open();
LOG("Inform called as: ");
for (i=0; i<argc; i++) LOG("%s ", argv[i]);
LOG("\n");
Config__Template__interpret(NULL, NULL, "Main.i6t", -1);
Problems__write_reports(FALSE);
Memory__free_memory();
LOG("Total of %d files written as streams.\n", total_file_writes);
clock_t end = clock();
int cpu_time_used = ((int) (end - start)) / (CLOCKS_PER_SEC/100);
LOG("CPU time: %d centiseconds\n", cpu_time_used);
Log__close();
if (report_clock_time) {
STREAM_WRITE(STDOUT, "%s has finished: %d centiseconds used.\n",
NI_VERSION, cpu_time_used);
} else {
STREAM_WRITE(STDOUT, "%s has finished.\n", NI_VERSION);
}
STREAM_FLUSH(STDOUT);
if (problem_count > 0) return 1; return 0;
}
void what_day_is_it(void) {
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);
}
char *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 160 "inform7/Chapter 27/I6 Template Interpreter.w"
int no_segments_noted = 0;
void Config__Template__interpret(OUTPUT_STREAM, 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) I6T_file_intervene(OUT, -1, segment_name, NULL);
if ((segment_name) && (I6T_file_intervene(OUT, 0, segment_name, NULL))) goto OmitFile;
if (segment_name) {
{
#line 253 "inform7/Chapter 27/I6 Template Interpreter.w"
char the_filename[MAX_FILENAME_LENGTH];
{
#line 272 "inform7/Chapter 27/I6 Template Interpreter.w"
sprintf(the_filename, "%s%cI6T%c%s",
materials_folder,
FOLDER_SEPARATOR, FOLDER_SEPARATOR, segment_name);
Input_File = Platform__iso_fopen(the_filename, "r");
}
#line 254 "inform7/Chapter 27/I6 Template Interpreter.w"
;
if (Input_File == NULL) {
{
#line 280 "inform7/Chapter 27/I6 Template Interpreter.w"
sprintf(the_filename, "%s%cReserved%c%s",
pathname_of_built_in_extensions,
FOLDER_SEPARATOR, FOLDER_SEPARATOR, segment_name);
Input_File = Platform__iso_fopen(the_filename, "r");
}
#line 256 "inform7/Chapter 27/I6 Template Interpreter.w"
;
if (Input_File == NULL) {
if (strcmp(segment_name, "Main.i6t") == 0)
Problems__Fatal__issue2("Error: can't open input file", segment_name);
STREAM_WRITE(STDERR, "inform: Unable to open segment <%s>\n", segment_name);
Problems__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 27/I6 Template Interpreter.w"
;
comment = TRUE;
} else comment = FALSE;
do {
{
#line 293 "inform7/Chapter 27/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 27/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 NI has thrown an exception */
fclose(Input_File); exit(0);
}
if ((cr == '@') && (col == 1)) {
int inweb_syntax = -1;
{
#line 308 "inform7/Chapter 27/I6 Template Interpreter.w"
int i = 0, committed = FALSE, unacceptable_character = FALSE;
while (i<MAX_I6T_LINE_LENGTH) {
{
#line 293 "inform7/Chapter 27/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 310 "inform7/Chapter 27/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)) {
STREAM_PUT(OUT, '@');
int j;
for (j=0; j<i; j++) STREAM_PUT(OUT, I6T_buffer[j]);
STREAM_PUT(OUT, cr);
}
break;
} else {
LOG("heading begins: <%s>\n", I6T_buffer);
Problems__quote_text(1, I6T_buffer);
Problems__unlocated_problem(_P_(C27BadTemplateAtSign),
"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 27/I6 Template Interpreter.w"
;
{
#line 356 "inform7/Chapter 27/I6 Template Interpreter.w"
switch (inweb_syntax) {
case INWEB_PARAGRAPH_SYNTAX: {
int i;
if ((heading_name[0] != 0) && (segment_name))
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)
internal_error("Empty heading name in I6 template file");
comment = TRUE; skip_part = FALSE;
if (segment_name) {
I6T_file_intervene(OUT, -1, segment_name, heading_name);
if (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 27/I6 Template Interpreter.w"
;
continue;
}
if (comment == FALSE) {
if (default_command[0] != 0) {
if ((cr == 10) || (cr == 13)) continue; /* skip blank lines here */
{
#line 394 "inform7/Chapter 27/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 293 "inform7/Chapter 27/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 401 "inform7/Chapter 27/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 27/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 468 "inform7/Chapter 27/I6 Template Interpreter.w"
{
#line 504 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "open-file") == 0) {
if (OUT) internal_error("output file already open");
if (STREAM_OPEN_TO_FILE(inform6_file, Files__Filenames__build(I6_OUTPUT_LEAFNAME), ISO_ENC) == FALSE)
Problems__Fatal__issue("Can't open output file");
OUT = inform6_file;
continue;
}
if (strcmp(command, "close-file") == 0) {
if (OUT) STREAM_CLOSE(OUT);
OUT = NULL;
active = TRUE;
continue;
}
}
#line 468 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 523 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "lines") == 0) {
Extensions__IDs__truncated_strcpy(default_command, argument, MAX_I6T_COMMAND_LENGTH);
continue;
}
}
#line 469 "inform7/Chapter 27/I6 Template Interpreter.w"
;
if (active == FALSE) continue;
if (strcmp(command, "segment") == 0) { Config__Template__interpret(OUT, NULL, argument, -1); continue; }
if (strcmp(command, "plugin") == 0) { Config__Plugins__command(argument); continue; }
if (strcmp(command, "type") == 0) { Kinds__Interpreter__despatch_kind_command(argument); continue; }
{
#line 535 "inform7/Chapter 27/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 477 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 601 "inform7/Chapter 27/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) {
Problems__Progress__update_progress_bar(atoi(argument), 0); continue;
}
}
#line 478 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 622 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "counter") == 0) {
if (OUT == NULL) continue;
WRITE("%d", Formats__Inform6__Labels__Counters__read(argument, NOT_APPLICABLE)); continue;
}
}
#line 479 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 635 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "value") == 0) {
if (OUT == NULL) continue;
{
#line 856 "inform7/Chapter 27/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 637 "inform7/Chapter 27/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(Data__Instances__count(K_door));
ALLOW_VALUE(Data__Instances__count(K_object));
ALLOW_VALUE(Data__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);
internal_error("Unknown {-value:...} value in I6 segment");
}
}
#line 480 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 670 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "read-assertions") == 0) {
if (strcmp(argument, "1") == 0) Parser__Assertions__traverse(1);
if (strcmp(argument, "2") == 0) Parser__Assertions__traverse(2);
if (problem_count > 0) active = FALSE;
continue;
}
}
#line 481 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 696 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "callv") == 0) {
{
#line 856 "inform7/Chapter 27/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 697 "inform7/Chapter 27/I6 Template Interpreter.w"
;
ALLOW_CALLV(Calculus__Deferrals__allow_no_further_deferrals);
ALLOW_CALLV(Code__Chronology__allow_no_further_past_tenses);
ALLOW_CALLV(Code__Phrases__add_rules_to_rulebooks);
ALLOW_CALLV(Code__Phrases__Adjectives__traverse);
ALLOW_CALLV(Code__Phrases__index_page_Phrasebook);
ALLOW_CALLV(Code__Phrases__parse_rule_parameters);
ALLOW_CALLV(Code__Phrases__parse_rule_placements);
ALLOW_CALLV(Code__Phrases__register_meanings);
ALLOW_CALLV(Code__Phrases__Timed__check_for_unused);
ALLOW_CALLV(Code__Phrases__traverse_for_names);
ALLOW_CALLV(Code__Phrases__traverse);
ALLOW_CALLV(Code__Rules__check_response_usages);
ALLOW_CALLV(Config__Plugins__start);
ALLOW_CALLV(Config__Template__report_unacted_upon_interventions);
ALLOW_CALLV(Data__Equations__index);
ALLOW_CALLV(Data__Equations__traverse_to_create);
ALLOW_CALLV(Data__Equations__traverse_to_stock);
ALLOW_CALLV(Data__NonlocalVariables__index_all);
ALLOW_CALLV(Data__Nametags__name_all);
ALLOW_CALLV(Data__Strings__allow_no_further_text_subs);
ALLOW_CALLV(Data__Tables__check_tables_for_kind_clashes);
ALLOW_CALLV(Data__Tables__complete);
ALLOW_CALLV(Data__Tables__index);
ALLOW_CALLV(Data__Tables__traverse_to_create);
ALLOW_CALLV(Data__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__log_statistics);
ALLOW_CALLV(Memory__free_memory);
ALLOW_CALLV(Memory__log_statistics);
ALLOW_CALLV(Memory__start);
ALLOW_CALLV(Parser__Nodes__plant_parse_tree);
ALLOW_CALLV(Parser__Nodes__verify);
ALLOW_CALLV(Parser__Sentences__break_source);
ALLOW_CALLV(Parser__Sentences__break_source);
ALLOW_CALLV(Parser__Sentences__create_standard_csps);
ALLOW_CALLV(Parser__Sentences__declare_source_loaded);
ALLOW_CALLV(Parser__Sentences__Headings__index);
ALLOW_CALLV(Parser__Sentences__Headings__make_tree);
ALLOW_CALLV(Parser__Sentences__Headings__satisfy_dependencies);
ALLOW_CALLV(Parser__Sentences__Headings__write_as_xml);
ALLOW_CALLV(Parser__Sentences__register_recently_lexed_phrases);
ALLOW_CALLV(Parser__Sentences__tidy_up_ofs_and_froms);
ALLOW_CALLV(Parser__Sentences__VPs__traverse);
ALLOW_CALLV(Parser__SP__debug_parser_statistics);
ALLOW_CALLV(Plugins__Actions__Index__page);
ALLOW_CALLV(Plugins__Actions__name_all);
ALLOW_CALLV(Plugins__Bibliographic__index_library_card);
ALLOW_CALLV(Plugins__Bibliographic__write_ifiction_and_blurb);
ALLOW_CALLV(Plugins__Figures__index_all);
ALLOW_CALLV(Plugins__Files__index_all);
ALLOW_CALLV(Plugins__Parsing__traverse);
ALLOW_CALLV(Plugins__Parsing__Verbs__prepare);
ALLOW_CALLV(Plugins__Scenes__index);
ALLOW_CALLV(Plugins__Sounds__index_all);
ALLOW_CALLV(Problems__empty_all_headings);
ALLOW_CALLV(Properties__Implementation__OfObjects__allocate_attributes);
ALLOW_CALLV(Properties__Measurement__validate_definitions);
ALLOW_CALLV(Semantics__BPs__make_built_in_further);
ALLOW_CALLV(Semantics__BPs__make_built_in);
ALLOW_CALLV(Semantics__Nouns__LiteralPatterns__define_named_phrases);
ALLOW_CALLV(Semantics__Quantifiers__make_built_in);
ALLOW_CALLV(Semantics__VerbUsage__log_all);
ALLOW_CALLV(Semantics__VerbUsage__stock);
ALLOW_CALLV(Text__Languages__log_language);
ALLOW_CALLV(Text__Languages__read_definition);
ALLOW_CALLV(Text__Reader__read_primary_source_text);
ALLOW_CALLV(Text__start);
ALLOW_CALLV(Text__traverse_for_plural_definitions);
ALLOW_CALLV(Kinds__Interpreter__include_templates_for_kinds);
ALLOW_CALLV(Kinds__Interpreter__batch_done);
ALLOW_CALLV(Specifications__Taxa__make_type_IDs_table);
ALLOW_CALLV(Specifications__Taxa__report_pairs_allowed);
ALLOW_CALLV(Specifications__Taxa__report_pairs_observed);
ALLOW_CALLV(World__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);
internal_error("Unknown {-callv:...} function in I6 segment");
}
}
#line 482 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 793 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "call") == 0) {
if (OUT == NULL) continue;
{
#line 856 "inform7/Chapter 27/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 795 "inform7/Chapter 27/I6 Template Interpreter.w"
;
ALLOW_CALL(Calculus__Propositions__compile_remaining_deferred);
ALLOW_CALL(Code__Activities__compile_activity_constants);
ALLOW_CALL(Code__Chronology__chronology_extents_i6_escape);
ALLOW_CALL(Code__Chronology__past_actions_i6_routines);
ALLOW_CALL(Code__Chronology__past_tenses_i6_escape);
ALLOW_CALL(Code__Phrases__compile_first_block);
ALLOW_CALL(Code__Phrases__compile_rule_printing_switch);
ALLOW_CALL(Code__Phrases__compile_rulebooks);
ALLOW_CALL(Code__Phrases__compile_as_needed);
ALLOW_CALL(Code__Phrases__Constants__compile_closures);
ALLOW_CALL(Code__Rulebooks__rulebook_var_creators_lookup);
ALLOW_CALL(Config__Inclusions__compile_icl_commands);
ALLOW_CALL(Config__Inclusions__UseOptions__compile);
ALLOW_CALL(Config__Plugins__define_IFDEF_symbols);
ALLOW_CALL(Config__Template__compile_build_number);
ALLOW_CALL(Data__Equations__compile);
ALLOW_CALL(Data__Lists__check);
ALLOW_CALL(Data__Lists__compile);
ALLOW_CALL(Data__Strings__compile_responses);
ALLOW_CALL(Data__Strings__compile);
ALLOW_CALL(Data__Tables__compile_max_score);
ALLOW_CALL(Data__Tables__compile_print_table_names);
ALLOW_CALL(Data__Tables__compile);
ALLOW_CALL(Formats__Inform6__Labels__Counters__compile_allocated_storage);
ALLOW_CALL(Plugins__Actions__compile_action_routines);
ALLOW_CALL(Plugins__Actions__Patterns__Named__compile);
ALLOW_CALL(Plugins__Bibliographic__compile_constants);
ALLOW_CALL(Plugins__Files__arrays);
ALLOW_CALL(Plugins__Parsing__TestScripts__compile_printout);
ALLOW_CALL(Plugins__Parsing__TestScripts__compile_switch);
ALLOW_CALL(Plugins__Parsing__TestScripts__write_text);
ALLOW_CALL(Plugins__Parsing__Tokens__Filters__compile);
ALLOW_CALL(Plugins__Parsing__Tokens__Values__compile_type_gprs);
ALLOW_CALL(Plugins__Parsing__Tokens__Values__number);
ALLOW_CALL(Plugins__Parsing__Tokens__Values__time);
ALLOW_CALL(Plugins__Parsing__Tokens__Values__truth_state);
ALLOW_CALL(Plugins__Parsing__Verbs__compile_all);
ALLOW_CALL(Plugins__Parsing__Verbs__compile_conditions);
ALLOW_CALL(Properties__alias_translations);
ALLOW_CALL(Properties__Implementation__OfObjects__compile_attributes);
ALLOW_CALL(Properties__Implementation__OfObjects__compile_stub_properties);
ALLOW_CALL(Properties__Measurement__Adjectives__compile_MADJ_routines);
ALLOW_CALL(Semantics__Adjectives__Meanings__agreements);
ALLOW_CALL(Semantics__Relations__compile_defined_relations);
ALLOW_CALL(Semantics__Relations__compile_defined_relation_constants);
ALLOW_CALL(Semantics__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__compile_runtime_id_structures);
ALLOW_CALL(Kinds__RunTime__compile_block_constants);
ALLOW_CALL(Plugins__Showme__compile_SHOWME_details);
ALLOW_CALL(World__Compile__compile);
LOG("command: <%s> argument: <%s>\n", command, argument);
internal_error("Unknown {-call:...} function in I6 segment");
}
}
#line 483 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 870 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "array") == 0) {
if (OUT == NULL) continue;
{
#line 856 "inform7/Chapter 27/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 872 "inform7/Chapter 27/I6 Template Interpreter.w"
;
ALLOW_ARRAY(Plugins__Actions__ActionCoding);
ALLOW_ARRAY(Plugins__Actions__ActionData);
ALLOW_ARRAY(Plugins__Actions__ActionHappened);
ALLOW_ARRAY(Code__Activities__Activity_after_rulebooks);
ALLOW_ARRAY(Code__Activities__Activity_atb_rulebooks);
ALLOW_ARRAY(Code__Activities__Activity_before_rulebooks);
ALLOW_ARRAY(Code__Activities__activity_var_creators);
ALLOW_ARRAY(Code__Activities__Activity_for_rulebooks);
ALLOW_ARRAY(Code__Phrases__TimedEventsTable);
ALLOW_ARRAY(Code__Phrases__TimedEventTimesTable);
ALLOW_ARRAY(Plugins__Player__InitialSituation);
ALLOW_ARRAY(Properties__Implementation__OfObjects__property_metadata);
ALLOW_ARRAY(Code__Rulebooks__rulebook_var_creators);
ALLOW_ARRAY(Code__Phrases__RulebookNames);
ALLOW_ARRAY(Code__Phrases__rulebooks_array);
ALLOW_ARRAY(Plugins__Figures__tableoffigures);
ALLOW_ARRAY(Plugins__Sounds__tableofsounds);
ALLOW_ARRAY(Plugins__Bibliographic__UUID_ARRAY);
LOG("command: <%s> argument: <%s>\n", command, argument);
internal_error("Unknown {-array:...} function in I6 segment");
}
}
#line 484 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 903 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "routine") == 0) {
if (OUT == NULL) continue;
{
#line 856 "inform7/Chapter 27/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 905 "inform7/Chapter 27/I6 Template Interpreter.w"
;
ALLOW_ROUTINE(Properties__Implementation__OfObjects__CreatePropertyOffsets);
ALLOW_ROUTINE(Kinds__RunTime__I7_Kind_Name);
ALLOW_ROUTINE(Code__Rulebooks__RulebookOutcomePrintingRule);
ALLOW_ROUTINE(Plugins__Scenes__DetectSceneChange);
ALLOW_ROUTINE(Plugins__Scenes__ShowSceneStatus);
ALLOW_ROUTINE(Plugins__Scenes__PrintSceneName);
ALLOW_ROUTINE(Extensions__Files__ShowExtensionVersions);
ALLOW_ROUTINE(Config__Inclusions__UseOptions__TestUseOption);
ALLOW_ROUTINE(Plugins__Parsing__Lines__MistakeActionSub);
ALLOW_ROUTINE(Plugins__Parsing__TestScripts__InternalTestCases);
ALLOW_ROUTINE(Semantics__ConjugateVerb);
LOG("command: <%s> argument: <%s>\n", command, argument);
internal_error("Unknown {-routine:...} function in I6 segment");
}
}
#line 485 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 927 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "testing-command") == 0) {
if (OUT == NULL) continue;
Plugins__Parsing__Verbs__reserve(argument);
WRITE("Verb meta '%s'\n", argument);
continue;
}
}
#line 486 "inform7/Chapter 27/I6 Template Interpreter.w"
;
LOG("command: <%s> argument: <%s>\n", command, argument);
Problems__quote_text(1, command);
Problems__unlocated_problem(_P_(C27BadTemplateInsertion),
"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 27/I6 Template Interpreter.w"
;
continue;
}
if (cr == '{') {
{
#line 293 "inform7/Chapter 27/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 27/I6 Template Interpreter.w"
;
if (cr == '-') {
{
#line 415 "inform7/Chapter 27/I6 Template Interpreter.w"
int i=0;
while (i<MAX_I6T_LINE_LENGTH) {
{
#line 293 "inform7/Chapter 27/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 417 "inform7/Chapter 27/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 27/I6 Template Interpreter.w"
;
if (command[0] == '!') continue;
{
#line 468 "inform7/Chapter 27/I6 Template Interpreter.w"
{
#line 504 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "open-file") == 0) {
if (OUT) internal_error("output file already open");
if (STREAM_OPEN_TO_FILE(inform6_file, Files__Filenames__build(I6_OUTPUT_LEAFNAME), ISO_ENC) == FALSE)
Problems__Fatal__issue("Can't open output file");
OUT = inform6_file;
continue;
}
if (strcmp(command, "close-file") == 0) {
if (OUT) STREAM_CLOSE(OUT);
OUT = NULL;
active = TRUE;
continue;
}
}
#line 468 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 523 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "lines") == 0) {
Extensions__IDs__truncated_strcpy(default_command, argument, MAX_I6T_COMMAND_LENGTH);
continue;
}
}
#line 469 "inform7/Chapter 27/I6 Template Interpreter.w"
;
if (active == FALSE) continue;
if (strcmp(command, "segment") == 0) { Config__Template__interpret(OUT, NULL, argument, -1); continue; }
if (strcmp(command, "plugin") == 0) { Config__Plugins__command(argument); continue; }
if (strcmp(command, "type") == 0) { Kinds__Interpreter__despatch_kind_command(argument); continue; }
{
#line 535 "inform7/Chapter 27/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 477 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 601 "inform7/Chapter 27/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) {
Problems__Progress__update_progress_bar(atoi(argument), 0); continue;
}
}
#line 478 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 622 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "counter") == 0) {
if (OUT == NULL) continue;
WRITE("%d", Formats__Inform6__Labels__Counters__read(argument, NOT_APPLICABLE)); continue;
}
}
#line 479 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 635 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "value") == 0) {
if (OUT == NULL) continue;
{
#line 856 "inform7/Chapter 27/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 637 "inform7/Chapter 27/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(Data__Instances__count(K_door));
ALLOW_VALUE(Data__Instances__count(K_object));
ALLOW_VALUE(Data__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);
internal_error("Unknown {-value:...} value in I6 segment");
}
}
#line 480 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 670 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "read-assertions") == 0) {
if (strcmp(argument, "1") == 0) Parser__Assertions__traverse(1);
if (strcmp(argument, "2") == 0) Parser__Assertions__traverse(2);
if (problem_count > 0) active = FALSE;
continue;
}
}
#line 481 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 696 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "callv") == 0) {
{
#line 856 "inform7/Chapter 27/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 697 "inform7/Chapter 27/I6 Template Interpreter.w"
;
ALLOW_CALLV(Calculus__Deferrals__allow_no_further_deferrals);
ALLOW_CALLV(Code__Chronology__allow_no_further_past_tenses);
ALLOW_CALLV(Code__Phrases__add_rules_to_rulebooks);
ALLOW_CALLV(Code__Phrases__Adjectives__traverse);
ALLOW_CALLV(Code__Phrases__index_page_Phrasebook);
ALLOW_CALLV(Code__Phrases__parse_rule_parameters);
ALLOW_CALLV(Code__Phrases__parse_rule_placements);
ALLOW_CALLV(Code__Phrases__register_meanings);
ALLOW_CALLV(Code__Phrases__Timed__check_for_unused);
ALLOW_CALLV(Code__Phrases__traverse_for_names);
ALLOW_CALLV(Code__Phrases__traverse);
ALLOW_CALLV(Code__Rules__check_response_usages);
ALLOW_CALLV(Config__Plugins__start);
ALLOW_CALLV(Config__Template__report_unacted_upon_interventions);
ALLOW_CALLV(Data__Equations__index);
ALLOW_CALLV(Data__Equations__traverse_to_create);
ALLOW_CALLV(Data__Equations__traverse_to_stock);
ALLOW_CALLV(Data__NonlocalVariables__index_all);
ALLOW_CALLV(Data__Nametags__name_all);
ALLOW_CALLV(Data__Strings__allow_no_further_text_subs);
ALLOW_CALLV(Data__Tables__check_tables_for_kind_clashes);
ALLOW_CALLV(Data__Tables__complete);
ALLOW_CALLV(Data__Tables__index);
ALLOW_CALLV(Data__Tables__traverse_to_create);
ALLOW_CALLV(Data__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__log_statistics);
ALLOW_CALLV(Memory__free_memory);
ALLOW_CALLV(Memory__log_statistics);
ALLOW_CALLV(Memory__start);
ALLOW_CALLV(Parser__Nodes__plant_parse_tree);
ALLOW_CALLV(Parser__Nodes__verify);
ALLOW_CALLV(Parser__Sentences__break_source);
ALLOW_CALLV(Parser__Sentences__break_source);
ALLOW_CALLV(Parser__Sentences__create_standard_csps);
ALLOW_CALLV(Parser__Sentences__declare_source_loaded);
ALLOW_CALLV(Parser__Sentences__Headings__index);
ALLOW_CALLV(Parser__Sentences__Headings__make_tree);
ALLOW_CALLV(Parser__Sentences__Headings__satisfy_dependencies);
ALLOW_CALLV(Parser__Sentences__Headings__write_as_xml);
ALLOW_CALLV(Parser__Sentences__register_recently_lexed_phrases);
ALLOW_CALLV(Parser__Sentences__tidy_up_ofs_and_froms);
ALLOW_CALLV(Parser__Sentences__VPs__traverse);
ALLOW_CALLV(Parser__SP__debug_parser_statistics);
ALLOW_CALLV(Plugins__Actions__Index__page);
ALLOW_CALLV(Plugins__Actions__name_all);
ALLOW_CALLV(Plugins__Bibliographic__index_library_card);
ALLOW_CALLV(Plugins__Bibliographic__write_ifiction_and_blurb);
ALLOW_CALLV(Plugins__Figures__index_all);
ALLOW_CALLV(Plugins__Files__index_all);
ALLOW_CALLV(Plugins__Parsing__traverse);
ALLOW_CALLV(Plugins__Parsing__Verbs__prepare);
ALLOW_CALLV(Plugins__Scenes__index);
ALLOW_CALLV(Plugins__Sounds__index_all);
ALLOW_CALLV(Problems__empty_all_headings);
ALLOW_CALLV(Properties__Implementation__OfObjects__allocate_attributes);
ALLOW_CALLV(Properties__Measurement__validate_definitions);
ALLOW_CALLV(Semantics__BPs__make_built_in_further);
ALLOW_CALLV(Semantics__BPs__make_built_in);
ALLOW_CALLV(Semantics__Nouns__LiteralPatterns__define_named_phrases);
ALLOW_CALLV(Semantics__Quantifiers__make_built_in);
ALLOW_CALLV(Semantics__VerbUsage__log_all);
ALLOW_CALLV(Semantics__VerbUsage__stock);
ALLOW_CALLV(Text__Languages__log_language);
ALLOW_CALLV(Text__Languages__read_definition);
ALLOW_CALLV(Text__Reader__read_primary_source_text);
ALLOW_CALLV(Text__start);
ALLOW_CALLV(Text__traverse_for_plural_definitions);
ALLOW_CALLV(Kinds__Interpreter__include_templates_for_kinds);
ALLOW_CALLV(Kinds__Interpreter__batch_done);
ALLOW_CALLV(Specifications__Taxa__make_type_IDs_table);
ALLOW_CALLV(Specifications__Taxa__report_pairs_allowed);
ALLOW_CALLV(Specifications__Taxa__report_pairs_observed);
ALLOW_CALLV(World__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);
internal_error("Unknown {-callv:...} function in I6 segment");
}
}
#line 482 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 793 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "call") == 0) {
if (OUT == NULL) continue;
{
#line 856 "inform7/Chapter 27/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 795 "inform7/Chapter 27/I6 Template Interpreter.w"
;
ALLOW_CALL(Calculus__Propositions__compile_remaining_deferred);
ALLOW_CALL(Code__Activities__compile_activity_constants);
ALLOW_CALL(Code__Chronology__chronology_extents_i6_escape);
ALLOW_CALL(Code__Chronology__past_actions_i6_routines);
ALLOW_CALL(Code__Chronology__past_tenses_i6_escape);
ALLOW_CALL(Code__Phrases__compile_first_block);
ALLOW_CALL(Code__Phrases__compile_rule_printing_switch);
ALLOW_CALL(Code__Phrases__compile_rulebooks);
ALLOW_CALL(Code__Phrases__compile_as_needed);
ALLOW_CALL(Code__Phrases__Constants__compile_closures);
ALLOW_CALL(Code__Rulebooks__rulebook_var_creators_lookup);
ALLOW_CALL(Config__Inclusions__compile_icl_commands);
ALLOW_CALL(Config__Inclusions__UseOptions__compile);
ALLOW_CALL(Config__Plugins__define_IFDEF_symbols);
ALLOW_CALL(Config__Template__compile_build_number);
ALLOW_CALL(Data__Equations__compile);
ALLOW_CALL(Data__Lists__check);
ALLOW_CALL(Data__Lists__compile);
ALLOW_CALL(Data__Strings__compile_responses);
ALLOW_CALL(Data__Strings__compile);
ALLOW_CALL(Data__Tables__compile_max_score);
ALLOW_CALL(Data__Tables__compile_print_table_names);
ALLOW_CALL(Data__Tables__compile);
ALLOW_CALL(Formats__Inform6__Labels__Counters__compile_allocated_storage);
ALLOW_CALL(Plugins__Actions__compile_action_routines);
ALLOW_CALL(Plugins__Actions__Patterns__Named__compile);
ALLOW_CALL(Plugins__Bibliographic__compile_constants);
ALLOW_CALL(Plugins__Files__arrays);
ALLOW_CALL(Plugins__Parsing__TestScripts__compile_printout);
ALLOW_CALL(Plugins__Parsing__TestScripts__compile_switch);
ALLOW_CALL(Plugins__Parsing__TestScripts__write_text);
ALLOW_CALL(Plugins__Parsing__Tokens__Filters__compile);
ALLOW_CALL(Plugins__Parsing__Tokens__Values__compile_type_gprs);
ALLOW_CALL(Plugins__Parsing__Tokens__Values__number);
ALLOW_CALL(Plugins__Parsing__Tokens__Values__time);
ALLOW_CALL(Plugins__Parsing__Tokens__Values__truth_state);
ALLOW_CALL(Plugins__Parsing__Verbs__compile_all);
ALLOW_CALL(Plugins__Parsing__Verbs__compile_conditions);
ALLOW_CALL(Properties__alias_translations);
ALLOW_CALL(Properties__Implementation__OfObjects__compile_attributes);
ALLOW_CALL(Properties__Implementation__OfObjects__compile_stub_properties);
ALLOW_CALL(Properties__Measurement__Adjectives__compile_MADJ_routines);
ALLOW_CALL(Semantics__Adjectives__Meanings__agreements);
ALLOW_CALL(Semantics__Relations__compile_defined_relations);
ALLOW_CALL(Semantics__Relations__compile_defined_relation_constants);
ALLOW_CALL(Semantics__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__compile_runtime_id_structures);
ALLOW_CALL(Kinds__RunTime__compile_block_constants);
ALLOW_CALL(Plugins__Showme__compile_SHOWME_details);
ALLOW_CALL(World__Compile__compile);
LOG("command: <%s> argument: <%s>\n", command, argument);
internal_error("Unknown {-call:...} function in I6 segment");
}
}
#line 483 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 870 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "array") == 0) {
if (OUT == NULL) continue;
{
#line 856 "inform7/Chapter 27/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 872 "inform7/Chapter 27/I6 Template Interpreter.w"
;
ALLOW_ARRAY(Plugins__Actions__ActionCoding);
ALLOW_ARRAY(Plugins__Actions__ActionData);
ALLOW_ARRAY(Plugins__Actions__ActionHappened);
ALLOW_ARRAY(Code__Activities__Activity_after_rulebooks);
ALLOW_ARRAY(Code__Activities__Activity_atb_rulebooks);
ALLOW_ARRAY(Code__Activities__Activity_before_rulebooks);
ALLOW_ARRAY(Code__Activities__activity_var_creators);
ALLOW_ARRAY(Code__Activities__Activity_for_rulebooks);
ALLOW_ARRAY(Code__Phrases__TimedEventsTable);
ALLOW_ARRAY(Code__Phrases__TimedEventTimesTable);
ALLOW_ARRAY(Plugins__Player__InitialSituation);
ALLOW_ARRAY(Properties__Implementation__OfObjects__property_metadata);
ALLOW_ARRAY(Code__Rulebooks__rulebook_var_creators);
ALLOW_ARRAY(Code__Phrases__RulebookNames);
ALLOW_ARRAY(Code__Phrases__rulebooks_array);
ALLOW_ARRAY(Plugins__Figures__tableoffigures);
ALLOW_ARRAY(Plugins__Sounds__tableofsounds);
ALLOW_ARRAY(Plugins__Bibliographic__UUID_ARRAY);
LOG("command: <%s> argument: <%s>\n", command, argument);
internal_error("Unknown {-array:...} function in I6 segment");
}
}
#line 484 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 903 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "routine") == 0) {
if (OUT == NULL) continue;
{
#line 856 "inform7/Chapter 27/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 905 "inform7/Chapter 27/I6 Template Interpreter.w"
;
ALLOW_ROUTINE(Properties__Implementation__OfObjects__CreatePropertyOffsets);
ALLOW_ROUTINE(Kinds__RunTime__I7_Kind_Name);
ALLOW_ROUTINE(Code__Rulebooks__RulebookOutcomePrintingRule);
ALLOW_ROUTINE(Plugins__Scenes__DetectSceneChange);
ALLOW_ROUTINE(Plugins__Scenes__ShowSceneStatus);
ALLOW_ROUTINE(Plugins__Scenes__PrintSceneName);
ALLOW_ROUTINE(Extensions__Files__ShowExtensionVersions);
ALLOW_ROUTINE(Config__Inclusions__UseOptions__TestUseOption);
ALLOW_ROUTINE(Plugins__Parsing__Lines__MistakeActionSub);
ALLOW_ROUTINE(Plugins__Parsing__TestScripts__InternalTestCases);
ALLOW_ROUTINE(Semantics__ConjugateVerb);
LOG("command: <%s> argument: <%s>\n", command, argument);
internal_error("Unknown {-routine:...} function in I6 segment");
}
}
#line 485 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 927 "inform7/Chapter 27/I6 Template Interpreter.w"
if (strcmp(command, "testing-command") == 0) {
if (OUT == NULL) continue;
Plugins__Parsing__Verbs__reserve(argument);
WRITE("Verb meta '%s'\n", argument);
continue;
}
}
#line 486 "inform7/Chapter 27/I6 Template Interpreter.w"
;
LOG("command: <%s> argument: <%s>\n", command, argument);
Problems__quote_text(1, command);
Problems__unlocated_problem(_P_(C27BadTemplateInsertion),
"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 27/I6 Template Interpreter.w"
;
continue;
} else if ((cr == 'N') && (N_escape >= 0)) {
{
#line 293 "inform7/Chapter 27/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 27/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)) STREAM_PUT(OUT, '{');
goto NewCharacter;
}
}
if (cr == '(') {
{
#line 293 "inform7/Chapter 27/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 27/I6 Template Interpreter.w"
;
if (cr == '+') {
{
#line 434 "inform7/Chapter 27/I6 Template Interpreter.w"
int i=0;
while (i<MAX_I6T_LINE_LENGTH) {
{
#line 293 "inform7/Chapter 27/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 436 "inform7/Chapter 27/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 27/I6 Template Interpreter.w"
;
{
#line 445 "inform7/Chapter 27/I6 Template Interpreter.w"
TEMPORARY_STREAM;
Config__Template__compile_I7_from_I6(TEMP, I6T_buffer);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
#line 224 "inform7/Chapter 27/I6 Template Interpreter.w"
;
continue;
} else { /* otherwise the open bracket was a literal */
if ((OUT) && (active)) STREAM_PUT(OUT, '(');
goto NewCharacter;
}
}
if ((OUT) && (active)) STREAM_PUT(OUT, cr);
}
} while (cr != EOF);
if (Input_File) { if (dl) STREAM_FLUSH(dl); fclose(Input_File); }
if ((heading_name[0] != 0) && (segment_name))
I6T_file_intervene(OUT, 1, segment_name, heading_name);
OmitFile:
if (segment_name) I6T_file_intervene(OUT, 1, segment_name, NULL);
}
#line 942 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__compile_I7_from_I6(OUTPUT_STREAM, char *p) {
Text__feed_into_lexer(p, FALSE, NULL);
int lw1 = lexer_feed_w1, lw2 = lexer_feed_w2;
if (parse_nt_against_word_range(property_name_NTM, lw1, lw2, NULL, NULL)) {
WRITE("%s", Properties__get_translation(most_recent_result_p));
return;
}
if (parse_nt_against_word_range(k_kind_NTM, lw1, lw2, NULL, NULL)) {
kind *K = most_recent_result_p;
if (Kinds__lt(K, K_object)) {
WRITE("%s", Kinds__I6_classname(K));
return;
}
}
instance *I = Data__Instances__parse_object(lw1, lw2);
if (I) {
WRITE("%s", Data__Instances__identifier(I));
return;
}
adjectival_phrase *aph = Semantics__Adjectives__Phrases__parse(lw1, lw2);
if (aph) {
if (Semantics__Adjectives__Phrases__write_adjective_test_routine(OUT, aph)) return;
Problems__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;
specification *spec = NULL;
if (parse_nt_against_word_range(spec_value_NTM, lw1, lw2, NULL, NULL)) spec = most_recent_result_p;
else spec = Specifications__Unknown__new(lw1, lw2);
if (initial_problem_count < problem_count) return;
Specifications__Matching__check_without_expectations(spec);
if (initial_problem_count < problem_count) return;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__compile(OUT, spec);
END_COMPILATION_MODE;
}
#line 991 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__new_intervention(int stage, char *segment, char *part, 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 1019 "inform7/Chapter 27/I6 Template Interpreter.w"
int 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) Config__Template__interpret(OUT, i6ti->I6T_matter, NULL, -1);
if (i6ti->alternative_segment) Config__Template__interpret(OUT, NULL, i6ti->alternative_segment, -1);
if (stage == 0) rv = TRUE;
}
return rv;
}
#line 1046 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__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;
Problems__sentence_problem(_P_(C27NoSuchTemplate),
"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__sentence_problem(_P_(C27NoSuchPart),
"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 1077 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__compile_build_number(OUTPUT_STREAM) {
WRITE("Constant NI_BUILD_COUNT \"%s\";\n", NI_BUILD);
}
#line 1087 "inform7/Chapter 27/I6 Template Interpreter.w"
void Config__Template__register_sentence_handlers(void) {
{
#line 1096 "inform7/Chapter 27/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 1088 "inform7/Chapter 27/I6 Template Interpreter.w"
;
{
#line 1112 "inform7/Chapter 27/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 1089 "inform7/Chapter 27/I6 Template Interpreter.w"
;
}
#line 74 "inform7/Chapter 27/Plugins.w"
int plugin_name_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
*X = R[0];
return TRUE;
}
#line 93 "inform7/Chapter 27/Plugins.w"
#line 99 "inform7/Chapter 27/Plugins.w"
int language_element_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 101 "inform7/Chapter 27/Plugins.w"
#line 105 "inform7/Chapter 27/Plugins.w"
word_assemblage plugin_wording(int N) {
return Text__Languages__wording(plugin_name_NTM, N);
}
#line 148 "inform7/Chapter 27/Plugins.w"
void Config__Plugins__start(void) {
initialise_plugin_calls();
CREATE_PLUGIN(core_plugin, 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, Plugins__Naming__start, FALSE,
NAMING_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(counting_plugin, Plugins__Counting__start, TRUE,
INSTANCE_COUNTING_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(parsing_plugin, Plugins__Parsing__start, FALSE,
COMMAND_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(actions_plugin, Plugins__Actions__start, FALSE,
ACTIONS_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
actions_plugin->has_template_file = "Actions";
CREATE_PLUGIN(spatial_plugin, Plugins__Spatial__start, TRUE,
SPATIAL_MODEL_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(map_plugin, Plugins__Map__start, FALSE,
MAPPING_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(player_plugin, Plugins__Player__start, FALSE,
PLAYER_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(regions_plugin, Plugins__Regions__start, TRUE,
REGIONS_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(backdrops_plugin, Plugins__Backdrops__start, FALSE,
BACKDROPS_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(showme_plugin, Plugins__Showme__start, FALSE,
SHOWME_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(times_plugin, Plugins__Times__start, FALSE,
TIMES_OF_DAY_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
times_plugin->has_template_file = "Times";
CREATE_PLUGIN(scenes_plugin, Plugins__Scenes__start, FALSE,
SCENES_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
scenes_plugin->has_template_file = "Scenes";
CREATE_PLUGIN(figures_plugin, Plugins__Figures__start, FALSE,
FIGURES_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
figures_plugin->has_template_file = "Figures";
CREATE_PLUGIN(sounds_plugin, Plugins__Sounds__start, FALSE,
SOUNDS_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
sounds_plugin->has_template_file = "Sounds";
CREATE_PLUGIN(files_plugin, Plugins__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, Plugins__Bibliographic__start, FALSE,
BIBLIOGRAPHIC_DATA_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
}
void start_core(void) {
}
#line 225 "inform7/Chapter 27/Plugins.w"
int use_language_element_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, int w1, int w2) {
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 233 "inform7/Chapter 27/Plugins.w"
*X = -1;
Problems__sentence_problem(_P_(C27NoSuchLanguageElement),
"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 228 "inform7/Chapter 27/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 229 "inform7/Chapter 27/Plugins.w"
#line 246 "inform7/Chapter 27/Plugins.w"
void Config__Plugins__plug_in(int w1, int w2) {
if (parse_nt_against_word_range(use_language_element_sentence_subject_NTM, w1, w2, 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 276 "inform7/Chapter 27/Plugins.w"
Problems__sentence_problem(_P_(C27DontRemoveTheCore),
"the core of the Inform language cannot be removed",
"because then what should we do? What should we ever do?");
return;
}
#line 262 "inform7/Chapter 27/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 284 "inform7/Chapter 27/Plugins.w"
void Config__Plugins__show_configuration(OUTPUT_STREAM) {
WRITE("<p>");
Index__anchor("CONFIG");
WRITE("Inform language definition:");
show_plugins(OUT, "Included", TRUE);
show_plugins(OUT, "Excluded", FALSE);
WRITE("<p>\n");
}
void show_plugins(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(", ");
Text__Words__copy_to_stream(OUT, &(P->plugin_name));
c++;
}
if (c == 0) WRITE("<i>none</i>");
}
#line 308 "inform7/Chapter 27/Plugins.w"
void Config__Plugins__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 318 "inform7/Chapter 27/Plugins.w"
void Config__Plugins__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);
Config__Template__interpret(NULL, NULL, segment_name, -1);
}
}
return;
}
internal_error("No such plugin command");
}
int Config__Plugins__plugged_in(plugin *P) {
return P->now_plugged_in;
}
#line 366 "inform7/Chapter 27/Plugins.w"
void initialise_plugin_calls(void) {
int i;
for (i=0; i<MAX_PLUGS; i++) plugins_stack[i] = NULL;
}
#line 409 "inform7/Chapter 27/Plugins.w"
int Config__Plugins__Call__name_to_early_infs(int w1, int w2, inference_subject **infs) {
PLUGINS_CALL(PLUGIN_NAME_TO_EARLY_INFS, w1, w2, infs);
}
int Config__Plugins__Call__new_variable_notify(nonlocal_variable *q) {
PLUGINS_CALL(PLUGIN_NEW_VARIABLE_NOTIFY, q);
}
int Config__Plugins__Call__new_base_kind_notify(kind *K, char *d, int w1, int w2) {
PLUGINS_CALL(PLUGIN_NEW_BASE_KIND_NOTIFY, K, d, w1, w2);
}
int Config__Plugins__Call__compile_constant(OUTPUT_STREAM, kind *K, specification *spec) {
PLUGINS_CALL(PLUGIN_COMPILE_CONSTANT, OUT, K, spec);
}
int Config__Plugins__Call__new_subject_notify(inference_subject *subj) {
PLUGINS_CALL(PLUGIN_NEW_SUBJECT_NOTIFY, subj);
}
int Config__Plugins__Call__new_named_instance_notify(instance *nc) {
PLUGINS_CALL(PLUGIN_NEW_INSTANCE_NOTIFY, nc);
}
int Config__Plugins__Call__new_permission_notify(property_permission *pp) {
PLUGINS_CALL(PLUGIN_NEW_PERMISSION_NOTIFY, pp);
}
int Config__Plugins__Call__irregular_genitive(inference_subject *owner, char *genitive, int *propriety) {
PLUGINS_CALL(PLUGIN_IRREGULAR_GENITIVE, owner, genitive, propriety);
}
int Config__Plugins__Call__set_kind_notify(instance *I, kind *k) {
PLUGINS_CALL(PLUGIN_SET_KIND_NOTIFY, I, k);
}
int Config__Plugins__Call__set_subkind_notify(kind *sub, kind *super) {
PLUGINS_CALL(PLUGIN_SET_SUBKIND_NOTIFY, sub, super);
}
int Config__Plugins__Call__complete_model(int stage) {
World__Inferences__diversion_off();
PLUGINS_CALL(PLUGIN_COMPLETE_MODEL, stage);
}
int Config__Plugins__Call__parse_composite_NQs(int *w1, int *w2,
int *determiner_w1, int *determiner_w2,
quantifier **quantifier_used, kind **some_kind) {
PLUGINS_CALL(PLUGIN_PARSE_COMPOSITE_NQS, w1, w2,
determiner_w1, determiner_w2, quantifier_used, some_kind);
}
int Config__Plugins__Call__refine_implicit_noun(parse_node *p) {
PLUGINS_CALL(PLUGIN_REFINE_IMPLICIT_NOUN, p);
}
int Config__Plugins__Call__act_on_special_NPs(parse_node *p) {
PLUGINS_CALL(PLUGIN_ACT_ON_SPECIAL_NPS, p);
}
int Config__Plugins__Call__new_property_notify(property *prn) {
PLUGINS_CALL(PLUGIN_NEW_PROPERTY_NOTIFY, prn);
}
int Config__Plugins__Call__property_value_notify(property *prn, specification *val) {
PLUGINS_CALL(PLUGIN_PROPERTY_VALUE_NOTIFY, prn, val);
}
int Config__Plugins__Call__more_specific(instance *I1, instance *I2) {
PLUGINS_CALL(PLUGIN_MORE_SPECIFIC, I1, I2);
}
int Config__Plugins__Call__inferences_contradict(inference *A, inference *B, int similarity) {
PLUGINS_CALL(PLUGIN_INFERENCES_CONTRADICT, A, B, similarity);
}
int Config__Plugins__Call__explain_contradiction(inference *A, inference *B, int similarity,
inference_subject *subj) {
PLUGINS_CALL(PLUGIN_EXPLAIN_CONTRADICTION, A, B, similarity, subj);
}
int Config__Plugins__Call__intervene_in_assertion(parse_node *px, parse_node *py) {
PLUGINS_CALL(PLUGIN_INTERVENE_IN_ASSERTION, px, py);
}
int Config__Plugins__Call__log_inference_type(int it) {
PLUGINS_CALL(PLUGIN_LOG_INFERENCE_TYPE, it);
}
int Config__Plugins__Call__compile_object_header(OUTPUT_STREAM, instance *I) {
PLUGINS_CALL(PLUGIN_COMPILE_OBJECT_HEADER, OUT, I);
}
int Config__Plugins__Call__estimate_property_usage(kind *k, int *words_used) {
PLUGINS_CALL(PLUGIN_ESTIMATE_PROPERTY_USAGE, k, words_used);
}
int Config__Plugins__Call__check_going(specification *from, specification *to,
specification *by, specification *through, specification *pushing) {
PLUGINS_CALL(PLUGIN_CHECK_GOING, from, to, by, through, pushing);
}
int Config__Plugins__Call__compile_model_tables(OUTPUT_STREAM) {
PLUGINS_CALL(PLUGIN_COMPILE_MODEL_TABLES, OUT);
}
int Config__Plugins__Call__default_appearance(inference_subject *infs, specification *txt) {
PLUGINS_CALL(PLUGIN_DEFAULT_APPEARANCE, infs, txt);
}
int Config__Plugins__Call__offered_property(kind *K, specification *owner, parse_node *what) {
PLUGINS_CALL(PLUGIN_OFFERED_PROPERTY, K, owner, what);
}
int Config__Plugins__Call__offered_specification(specification *owner, int w1, int w2) {
PLUGINS_CALL(PLUGIN_OFFERED_SPECIFICATION, owner, w1, w2);
}
int Config__Plugins__Call__typecheck_equality(kind *K1, kind *K2) {
PLUGINS_CALL(PLUGIN_TYPECHECK_EQUALITY, K1, K2);
}
int Config__Plugins__Call__forbid_setting(kind *K) {
PLUGINS_CALL(PLUGIN_FORBID_SETTING, K);
}
int Config__Plugins__Call__variable_set_warning(nonlocal_variable *q, specification *val) {
PLUGINS_CALL(PLUGIN_VARIABLE_SET_WARNING, q, val);
}
int Config__Plugins__Call__detect_bodysnatching(inference_subject *body, int *snatcher,
inference_subject **counterpart) {
PLUGINS_CALL(PLUGIN_DETECT_BODYSNATCHING, body, snatcher, counterpart);
}
int Config__Plugins__Call__add_to_World_index(instance *O) {
PLUGINS_CALL(PLUGIN_ADD_TO_WORLD_INDEX, O);
}
int Config__Plugins__Call__annotate_in_World_index(instance *O) {
PLUGINS_CALL(PLUGIN_ANNOTATE_IN_WORLD_INDEX, O);
}
void register_tangled_nonterminals(void) {
#line 85 "inform7/Chapter 2/Make Inform 6 Names.w"
REGISTER_NONTERMINAL("<translates-into-i6-sentence-subject>", translates_into_i6_sentence_subject_NTM);
#line 110 "inform7/Chapter 2/Make Inform 6 Names.w"
REGISTER_NONTERMINAL("<translates-into-i6-sentence-object>", translates_into_i6_sentence_object_NTM);
#line 193 "inform7/Chapter 2/Make Inform 6 Names.w"
REGISTER_NONTERMINAL("<extra-response>", extra_response_NTM);
#line 69 "inform7/Chapter 3/HTML Documentation.w"
REGISTER_NONTERMINAL("<extension-documentation-heading>", extension_documentation_heading_NTM);
#line 97 "inform7/Chapter 3/HTML Documentation.w"
REGISTER_NONTERMINAL("<extension-example-header>", extension_example_header_NTM);
#line 101 "inform7/Chapter 3/HTML Documentation.w"
REGISTER_NONTERMINAL("<row-of-asterisks>", row_of_asterisks_NTM);
#line 304 "inform7/Chapter 3/HTML Documentation.w"
REGISTER_NONTERMINAL("<extension-documentation-paste-marker>", extension_documentation_paste_marker_NTM);
#line 934 "inform7/Chapter 3/Index File Services.w"
REGISTER_NONTERMINAL("<documentation-symbol-tail>", documentation_symbol_tail_NTM);
#line 938 "inform7/Chapter 3/Index File Services.w"
REGISTER_NONTERMINAL("<documentation-symbol>", documentation_symbol_NTM);
#line 421 "inform7/Chapter 4/Debugging Log.w"
REGISTER_NONTERMINAL("<include-in-debugging-sentence-subject>", include_in_debugging_sentence_subject_NTM);
#line 425 "inform7/Chapter 4/Debugging Log.w"
REGISTER_NONTERMINAL("<debugging-log-request>", debugging_log_request_NTM);
#line 95 "inform7/Chapter 5/Lexical Services.w"
INTERNAL_NONTERMINAL("<if-start-of-paragraph>", if_start_of_paragraph_NTM, 0, 0);
if_start_of_paragraph_NTM->voracious = 0;
#line 111 "inform7/Chapter 5/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 120 "inform7/Chapter 5/Lexical Services.w"
INTERNAL_NONTERMINAL("<if-not-deliberately-capitalised>", if_not_deliberately_capitalised_NTM, 0, 0);
if_not_deliberately_capitalised_NTM->voracious = 0;
#line 267 "inform7/Chapter 5/Lexical Services.w"
REGISTER_NONTERMINAL("<balanced-text>", balanced_text_NTM);
#line 301 "inform7/Chapter 5/Lexical Services.w"
REGISTER_NONTERMINAL("<list-comma-division>", list_comma_division_NTM);
#line 618 "inform7/Chapter 5/Tries and Inflections.w"
REGISTER_NONTERMINAL("<small-trie-test>", small_trie_test_NTM);
#line 286 "inform7/Chapter 5/Natural Languages.w"
INTERNAL_NONTERMINAL("<natural-language>", natural_language_NTM, 1, 1000000000);
natural_language_NTM->voracious = 0;
#line 471 "inform7/Chapter 5/Preform.w"
INTERNAL_NONTERMINAL("<preform-nonterminal>", preform_nonterminal_NTM, 1, 1);
preform_nonterminal_NTM->voracious = 0;
#line 355 "inform7/Chapter 6/Sentences.w"
REGISTER_NONTERMINAL("<dividing-sentence>", dividing_sentence_NTM);
#line 359 "inform7/Chapter 6/Sentences.w"
REGISTER_NONTERMINAL("<heading>", heading_NTM);
#line 366 "inform7/Chapter 6/Sentences.w"
REGISTER_NONTERMINAL("<extension-end-marker-sentence>", extension_end_marker_sentence_NTM);
#line 516 "inform7/Chapter 6/Sentences.w"
REGISTER_NONTERMINAL("<structural-sentence>", structural_sentence_NTM);
#line 533 "inform7/Chapter 6/Sentences.w"
REGISTER_NONTERMINAL("<language-modifying-sentence>", language_modifying_sentence_NTM);
#line 544 "inform7/Chapter 6/Sentences.w"
REGISTER_NONTERMINAL("<use-option-sentence-shape>", use_option_sentence_shape_NTM);
#line 604 "inform7/Chapter 6/Sentences.w"
REGISTER_NONTERMINAL("<comma-divisible-sentence>", comma_divisible_sentence_NTM);
#line 622 "inform7/Chapter 6/Sentences.w"
REGISTER_NONTERMINAL("<list-or-division>", list_or_division_NTM);
#line 222 "inform7/Chapter 6/Virtual Machines.w"
REGISTER_NONTERMINAL("<vm-description-list>", vm_description_list_NTM);
#line 227 "inform7/Chapter 6/Virtual Machines.w"
REGISTER_NONTERMINAL("<vm-description-tail>", vm_description_tail_NTM);
#line 231 "inform7/Chapter 6/Virtual Machines.w"
REGISTER_NONTERMINAL("<vm-description-entry>", vm_description_entry_NTM);
#line 238 "inform7/Chapter 6/Virtual Machines.w"
REGISTER_NONTERMINAL("<version-identification>", version_identification_NTM);
#line 309 "inform7/Chapter 6/Virtual Machines.w"
INTERNAL_NONTERMINAL("<virtual-machine>", virtual_machine_NTM, 1, 1000000000);
virtual_machine_NTM->voracious = 0;
#line 294 "inform7/Chapter 6/Headings.w"
REGISTER_NONTERMINAL("<heading-qualifier>", heading_qualifier_NTM);
#line 300 "inform7/Chapter 6/Headings.w"
REGISTER_NONTERMINAL("<bracketed-heading-qualifier>", bracketed_heading_qualifier_NTM);
#line 307 "inform7/Chapter 6/Headings.w"
REGISTER_NONTERMINAL("<platform-qualifier>", platform_qualifier_NTM);
#line 311 "inform7/Chapter 6/Headings.w"
REGISTER_NONTERMINAL("<platform-identifier>", platform_identifier_NTM);
#line 317 "inform7/Chapter 6/Headings.w"
REGISTER_NONTERMINAL("<extension-qualifier>", extension_qualifier_NTM);
#line 323 "inform7/Chapter 6/Headings.w"
REGISTER_NONTERMINAL("<extension-identifier>", extension_identifier_NTM);
#line 297 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<nonstructural-sentence>", nonstructural_sentence_NTM);
#line 496 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase>", nounphrase_NTM);
#line 499 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-definite>", nounphrase_definite_NTM);
#line 503 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-figure>", nounphrase_figure_NTM);
#line 506 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-sound>", nounphrase_sound_NTM);
#line 509 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-external-file>", nounphrase_external_file_NTM);
#line 512 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-actionable>", nounphrase_actionable_NTM);
#line 515 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<variable-creation-tail>", variable_creation_tail_NTM);
#line 522 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<translation-target>", translation_target_NTM);
#line 549 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<existential-sentence>", existential_sentence_NTM);
#line 573 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<existential-sentence-inner>", existential_sentence_inner_NTM);
#line 581 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<existential-sentence-inner-tail1>", existential_sentence_inner_tail1_NTM);
#line 585 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<existential-sentence-inner-tail2>", existential_sentence_inner_tail2_NTM);
#line 589 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<existential-sentence-inner-tail3>", existential_sentence_inner_tail3_NTM);
#line 646 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<certainty>", certainty_NTM);
#line 704 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence>", regular_sentence_NTM);
#line 714 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail1-without-rc>", regular_sentence_tail1_without_rc_NTM);
#line 720 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail2-without-rc>", regular_sentence_tail2_without_rc_NTM);
#line 726 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail3-without-rc>", regular_sentence_tail3_without_rc_NTM);
#line 732 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail4-without-rc>", regular_sentence_tail4_without_rc_NTM);
#line 738 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail1>", regular_sentence_tail1_NTM);
#line 742 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail2>", regular_sentence_tail2_NTM);
#line 746 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail3>", regular_sentence_tail3_NTM);
#line 750 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail4>", regular_sentence_tail4_NTM);
#line 784 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail1-inner>", regular_sentence_tail1_inner_NTM);
#line 790 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail2-inner>", regular_sentence_tail2_inner_NTM);
#line 796 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail3-inner>", regular_sentence_tail3_inner_NTM);
#line 802 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail4-inner>", regular_sentence_tail4_inner_NTM);
#line 853 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<bad-nonstructural-sentence-diagnosis>", bad_nonstructural_sentence_diagnosis_NTM);
#line 856 "inform7/Chapter 6/Verb Phrases.w"
REGISTER_NONTERMINAL("<bad-nonstructural-sentence-diagnosis-tail>", bad_nonstructural_sentence_diagnosis_tail_NTM);
#line 69 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-articled>", nounphrase_articled_NTM);
#line 93 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-balanced>", np_balanced_NTM);
#line 97 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-articled-balanced>", np_articled_balanced_NTM);
#line 130 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-articled-list>", nounphrase_articled_list_NTM);
#line 135 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-articled-tail>", np_articled_tail_NTM);
#line 159 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-rule-list>", nounphrase_rule_list_NTM);
#line 164 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-rule-tail>", np_rule_tail_NTM);
#line 168 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-rule>", nounphrase_rule_NTM);
#line 178 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-alternative-list>", nounphrase_alternative_list_NTM);
#line 183 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-alternative-tail>", np_alternative_tail_NTM);
#line 202 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-as-object>", nounphrase_as_object_NTM);
#line 206 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-as-subject>", nounphrase_as_subject_NTM);
#line 211 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-inner>", np_inner_NTM);
#line 219 "inform7/Chapter 6/Noun Phrases.w"
INTERNAL_NONTERMINAL("<if-copular>", if_copular_NTM, 0, 0);
if_copular_NTM->voracious = 0;
#line 258 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-relative-phrase-limited>", np_relative_phrase_limited_NTM);
#line 264 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-relative-phrase-unlimited>", np_relative_phrase_unlimited_NTM);
#line 278 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-relative-phrase-exception>", np_relative_phrase_exception_NTM);
#line 297 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-relative-phrase-implicit>", np_relative_phrase_implicit_NTM);
#line 303 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-relative-phrase-explicit>", np_relative_phrase_explicit_NTM);
#line 382 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-inner-without-rp>", np_inner_without_rp_NTM);
#line 408 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-with-or-having-tail>", np_with_or_having_tail_NTM);
#line 413 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-new-property-list>", np_new_property_list_NTM);
#line 418 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-new-property>", np_new_property_NTM);
#line 421 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-new-property-tail>", np_new_property_tail_NTM);
#line 425 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-tail>", np_tail_NTM);
#line 437 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-kind-phrase>", np_kind_phrase_NTM);
#line 441 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-kind-phrase-unarticled>", np_kind_phrase_unarticled_NTM);
#line 454 "inform7/Chapter 6/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-from-or-of-tail>", np_from_or_of_tail_NTM);
#line 232 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<prohibited-property-owners>", prohibited_property_owners_NTM);
#line 242 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<action-name-formal>", action_name_formal_NTM);
#line 245 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<activity-name-formal>", activity_name_formal_NTM);
#line 248 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<relation-name-formal>", relation_name_formal_NTM);
#line 251 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<rule-name-formal>", rule_name_formal_NTM);
#line 254 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<rulebook-name-formal>", rulebook_name_formal_NTM);
#line 267 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<has-properties-called-sentence-object>", has_properties_called_sentence_object_NTM);
#line 271 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<has-property-name-tail>", has_property_name_tail_NTM);
#line 275 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<has-property-name>", has_property_name_NTM);
#line 279 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<bad-property-name-diagnosis>", bad_property_name_diagnosis_NTM);
#line 335 "inform7/Chapter 6/Of and From.w"
REGISTER_NONTERMINAL("<sentence-needing-second-look>", sentence_needing_second_look_NTM);
#line 616 "inform7/Chapter 6/Rule Subtrees.w"
REGISTER_NONTERMINAL("<control-structure-phrase>", control_structure_phrase_NTM);
#line 628 "inform7/Chapter 6/Rule Subtrees.w"
REGISTER_NONTERMINAL("<end-control-structure-phrase>", end_control_structure_phrase_NTM);
#line 636 "inform7/Chapter 6/Rule Subtrees.w"
REGISTER_NONTERMINAL("<phrase-beginning-block>", phrase_beginning_block_NTM);
#line 77 "inform7/Chapter 7/Including Extensions.w"
REGISTER_NONTERMINAL("<extension-title-and-version>", extension_title_and_version_NTM);
#line 82 "inform7/Chapter 7/Including Extensions.w"
REGISTER_NONTERMINAL("<extension-unversioned>", extension_unversioned_NTM);
#line 86 "inform7/Chapter 7/Including Extensions.w"
REGISTER_NONTERMINAL("<extension-unversioned-inner>", extension_unversioned_inner_NTM);
#line 103 "inform7/Chapter 7/Including Extensions.w"
INTERNAL_NONTERMINAL("<extension-version>", extension_version_NTM, 1, 1);
extension_version_NTM->voracious = 0;
#line 251 "inform7/Chapter 7/Including Extensions.w"
REGISTER_NONTERMINAL("<extension-body>", extension_body_NTM);
#line 367 "inform7/Chapter 7/Including Extensions.w"
REGISTER_NONTERMINAL("<begins-here-sentence-subject>", begins_here_sentence_subject_NTM);
#line 301 "inform7/Chapter 8/Traverse for Assertions.w"
REGISTER_NONTERMINAL("<no-verb-diagnosis>", no_verb_diagnosis_NTM);
#line 322 "inform7/Chapter 8/Refine Parse Tree.w"
REGISTER_NONTERMINAL("<kind-alias-syntax>", kind_alias_syntax_NTM);
#line 405 "inform7/Chapter 8/Refine Parse Tree.w"
REGISTER_NONTERMINAL("<newfound-property-of>", newfound_property_of_NTM);
#line 512 "inform7/Chapter 8/Refine Parse Tree.w"
REGISTER_NONTERMINAL("<assertion-np-as-value>", assertion_np_as_value_NTM);
#line 351 "inform7/Chapter 8/The Creator.w"
REGISTER_NONTERMINAL("<grammatical-gender-marker>", grammatical_gender_marker_NTM);
#line 354 "inform7/Chapter 8/The Creator.w"
REGISTER_NONTERMINAL("<grammatical-gender-abbreviation>", grammatical_gender_abbreviation_NTM);
#line 391 "inform7/Chapter 8/The Creator.w"
REGISTER_NONTERMINAL("<creation-problem-diagnosis>", creation_problem_diagnosis_NTM);
#line 938 "inform7/Chapter 8/The Creator.w"
REGISTER_NONTERMINAL("<text-ending-with-a-calling>", text_ending_with_a_calling_NTM);
#line 942 "inform7/Chapter 8/The Creator.w"
REGISTER_NONTERMINAL("<text-including-a-calling>", text_including_a_calling_NTM);
#line 955 "inform7/Chapter 8/The Creator.w"
REGISTER_NONTERMINAL("<unsuitable-name>", unsuitable_name_NTM);
#line 960 "inform7/Chapter 8/The Creator.w"
REGISTER_NONTERMINAL("<unsuitable-name-for-locals>", unsuitable_name_for_locals_NTM);
#line 965 "inform7/Chapter 8/The Creator.w"
REGISTER_NONTERMINAL("<unfortunate-name>", unfortunate_name_NTM);
#line 1689 "inform7/Chapter 8/Make Assertions.w"
REGISTER_NONTERMINAL("<something-loose-diagnosis>", something_loose_diagnosis_NTM);
#line 33 "inform7/Chapter 8/Property Declarations.w"
REGISTER_NONTERMINAL("<forbidden-property-owners>", forbidden_property_owners_NTM);
#line 131 "inform7/Chapter 8/Property Declarations.w"
REGISTER_NONTERMINAL("<can-be-sentence-object>", can_be_sentence_object_NTM);
#line 137 "inform7/Chapter 8/Property Declarations.w"
REGISTER_NONTERMINAL("<condition-name>", condition_name_NTM);
#line 141 "inform7/Chapter 8/Property Declarations.w"
REGISTER_NONTERMINAL("<condition-name-inner>", condition_name_inner_NTM);
#line 146 "inform7/Chapter 8/Property Declarations.w"
REGISTER_NONTERMINAL("<condition-name-innermost>", condition_name_innermost_NTM);
#line 74 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<singular-noun-to-its-indefinite-article>", singular_noun_to_its_indefinite_article_NTM);
#line 82 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-indef-a>", en_trie_indef_a_NTM);
#line 93 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-indef-b>", en_trie_indef_b_NTM);
#line 161 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-indef-c>", en_trie_indef_c_NTM);
#line 248 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<singular-noun-to-its-plural>", singular_noun_to_its_plural_NTM);
#line 262 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-uninflected>", en_trie_plural_uninflected_NTM);
#line 317 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-pronouns>", en_trie_plural_pronouns_NTM);
#line 345 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-irregular>", en_trie_plural_irregular_NTM);
#line 364 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-irregular-inflections>", en_trie_plural_irregular_inflections_NTM);
#line 380 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-assimilated-classical-inflections>", en_trie_plural_assimilated_classical_inflections_NTM);
#line 411 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-irregular-o-suffixes>", en_trie_plural_irregular_o_suffixes_NTM);
#line 449 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-regular-inflections>", en_trie_plural_regular_inflections_NTM);
#line 533 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-append-s>", en_trie_plural_append_s_NTM);
#line 653 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<verb-conjugation-instructions>", verb_conjugation_instructions_NTM);
#line 722 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-have-conjugation>", to_have_conjugation_NTM);
#line 812 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-have-tabulation>", to_have_tabulation_NTM);
#line 823 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-have-present>", to_have_present_NTM);
#line 860 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-do-conjugation>", to_do_conjugation_NTM);
#line 865 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-do-tabulation>", to_do_tabulation_NTM);
#line 876 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-do-present>", to_do_present_NTM);
#line 899 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<regular-verb-conjugation>", regular_verb_conjugation_NTM);
#line 917 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<regular-verb-tabulation>", regular_verb_tabulation_NTM);
#line 935 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<regular-verb-present>", regular_verb_present_NTM);
#line 941 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-conjugation>", to_be_conjugation_NTM);
#line 946 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-tabulation>", to_be_tabulation_NTM);
#line 956 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-present>", to_be_present_NTM);
#line 959 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-past>", to_be_past_NTM);
#line 981 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-able-to-conjugation>", to_be_able_to_conjugation_NTM);
#line 986 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-able-to-tabulation>", to_be_able_to_tabulation_NTM);
#line 1022 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-able-to-auxiliary>", to_be_able_to_auxiliary_NTM);
#line 1027 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-able-to-auxiliary-tabulation>", to_be_able_to_auxiliary_tabulation_NTM);
#line 1037 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<modal-conjugation>", modal_conjugation_NTM);
#line 1042 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<modal-tabulation>", modal_tabulation_NTM);
#line 1081 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-be-conjugation>", contracted_to_be_conjugation_NTM);
#line 1087 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-be-tabulation>", contracted_to_be_tabulation_NTM);
#line 1099 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-be-present>", contracted_to_be_present_NTM);
#line 1102 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-be-past>", contracted_to_be_past_NTM);
#line 1105 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-be-past-negated>", contracted_to_be_past_negated_NTM);
#line 1121 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-have-conjugation>", contracted_to_have_conjugation_NTM);
#line 1127 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-have-tabulation>", contracted_to_have_tabulation_NTM);
#line 1139 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-have-present>", contracted_to_have_present_NTM);
#line 1155 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<arent-conjugation>", arent_conjugation_NTM);
#line 1161 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<arent-tabulation>", arent_tabulation_NTM);
#line 1168 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<arent-present>", arent_present_NTM);
#line 1171 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<arent-past>", arent_past_NTM);
#line 1174 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<arent-perfect>", arent_perfect_NTM);
#line 1186 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<informal-negated-modal-conjugation>", informal_negated_modal_conjugation_NTM);
#line 1195 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<informal-negated-modal-tabulation>", informal_negated_modal_tabulation_NTM);
#line 1202 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<informal-negated-modal-present>", informal_negated_modal_present_NTM);
#line 1208 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<cant-modal-conjugation>", cant_modal_conjugation_NTM);
#line 1214 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<cant-modal-tabulation>", cant_modal_tabulation_NTM);
#line 1230 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-modal-contracted-present>", en_trie_modal_contracted_present_NTM);
#line 1242 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-modal-contracted-past>", en_trie_modal_contracted_past_NTM);
#line 1254 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-modal-contracted-future>", en_trie_modal_contracted_future_NTM);
#line 1314 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-present-participle>", en_trie_present_participle_NTM);
#line 1328 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-present-participle>", en_trie_irregular_present_participle_NTM);
#line 1518 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-compound-present-participle>", en_trie_irregular_compound_present_participle_NTM);
#line 1537 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-a-present-participle>", en_trie_regular_a_present_participle_NTM);
#line 1587 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-b-present-participle>", en_trie_regular_b_present_participle_NTM);
#line 1592 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-c-present-participle>", en_trie_regular_c_present_participle_NTM);
#line 1604 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-past-participle>", en_trie_past_participle_NTM);
#line 1608 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-past-participle>", en_trie_irregular_past_participle_NTM);
#line 1768 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-present-verb-form>", en_trie_present_verb_form_NTM);
#line 1772 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-third-person-present>", en_trie_irregular_third_person_present_NTM);
#line 1784 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-past>", en_trie_past_NTM);
#line 1791 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-past>", en_trie_irregular_past_NTM);
#line 2335 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-compound-past>", en_trie_irregular_compound_past_NTM);
#line 2351 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-a-past>", en_trie_regular_a_past_NTM);
#line 2398 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-b-past>", en_trie_regular_b_past_NTM);
#line 2403 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-c-past>", en_trie_regular_c_past_NTM);
#line 2430 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<pasturise-participle>", pasturise_participle_NTM);
#line 2435 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-pasturise-exceptions>", en_trie_pasturise_exceptions_NTM);
#line 2899 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-pasturise-regular-y>", en_trie_pasturise_regular_y_NTM);
#line 2902 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-pasturise-regular>", en_trie_pasturise_regular_NTM);
#line 2910 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<adjective-to-plural>", adjective_to_plural_NTM);
#line 2913 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<adjective-to-masculine-singular>", adjective_to_masculine_singular_NTM);
#line 2916 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<adjective-to-feminine-singular>", adjective_to_feminine_singular_NTM);
#line 2919 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<adjective-to-masculine-plural>", adjective_to_masculine_plural_NTM);
#line 2922 "inform7/Chapter 9/English Inflections.w"
REGISTER_NONTERMINAL("<adjective-to-feminine-plural>", adjective_to_feminine_plural_NTM);
#line 13 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<pronoun>", pronoun_NTM);
#line 17 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<nominative-pronoun>", nominative_pronoun_NTM);
#line 21 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<accusative-pronoun>", accusative_pronoun_NTM);
#line 33 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<possessive-first-person>", possessive_first_person_NTM);
#line 37 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<possessive-second-person>", possessive_second_person_NTM);
#line 41 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<possessive-third-person>", possessive_third_person_NTM);
#line 52 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<relative-clause-marker>", relative_clause_marker_NTM);
#line 58 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<article>", article_NTM);
#line 73 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<definite-article>", definite_article_NTM);
#line 76 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<indefinite-article>", indefinite_article_NTM);
#line 83 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<optional-definite-article>", optional_definite_article_NTM);
#line 87 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<optional-article>", optional_article_NTM);
#line 91 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<compulsory-article>", compulsory_article_NTM);
#line 114 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<non-participles>", non_participles_NTM);
#line 117 "inform7/Chapter 9/Articles and Pronouns.w"
INTERNAL_NONTERMINAL("<probable-participle>", probable_participle_NTM, 1, 1);
probable_participle_NTM->voracious = 0;
#line 128 "inform7/Chapter 9/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<negated-clause>", negated_clause_NTM);
#line 305 "inform7/Chapter 9/Determiners and Quantifiers.w"
REGISTER_NONTERMINAL("<determiner-names>", determiner_names_NTM);
#line 374 "inform7/Chapter 9/Determiners and Quantifiers.w"
REGISTER_NONTERMINAL("<determination-of>", determination_of_NTM);
#line 392 "inform7/Chapter 9/Determiners and Quantifiers.w"
REGISTER_NONTERMINAL("<excluded-from-determiners>", excluded_from_determiners_NTM);
#line 700 "inform7/Chapter 9/Binary Predicates.w"
INTERNAL_NONTERMINAL("<relation-name>", relation_name_NTM, 1, 1000000000);
relation_name_NTM->voracious = 0;
#line 66 "inform7/Chapter 9/Relations.w"
REGISTER_NONTERMINAL("<relation-names>", relation_names_NTM);
#line 109 "inform7/Chapter 9/Relations.w"
REGISTER_NONTERMINAL("<relates-sentence-subject>", relates_sentence_subject_NTM);
#line 256 "inform7/Chapter 9/Relations.w"
REGISTER_NONTERMINAL("<relates-sentence-left-object>", relates_sentence_left_object_NTM);
#line 260 "inform7/Chapter 9/Relations.w"
REGISTER_NONTERMINAL("<relates-sentence-right-object>", relates_sentence_right_object_NTM);
#line 265 "inform7/Chapter 9/Relations.w"
REGISTER_NONTERMINAL("<relation-term-right-named>", relation_term_right_named_NTM);
#line 269 "inform7/Chapter 9/Relations.w"
REGISTER_NONTERMINAL("<relation-term-right>", relation_term_right_NTM);
#line 275 "inform7/Chapter 9/Relations.w"
REGISTER_NONTERMINAL("<relation-term-basic>", relation_term_basic_NTM);
#line 234 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<general-verb>", general_verb_NTM, 1, 1000000000);
general_verb_NTM->voracious = 1;
#line 251 "inform7/Chapter 9/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 273 "inform7/Chapter 9/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 297 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<copular-verb>", copular_verb_NTM, 1, 1000000000);
copular_verb_NTM->voracious = 1;
#line 317 "inform7/Chapter 9/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 342 "inform7/Chapter 9/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 365 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<universal-verb>", universal_verb_NTM, 1, 1000000000);
universal_verb_NTM->voracious = 1;
#line 384 "inform7/Chapter 9/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 407 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<negated-verb>", negated_verb_NTM, 1, 1000000000);
negated_verb_NTM->voracious = 1;
#line 427 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<past-tense-verb>", past_tense_verb_NTM, 1, 1000000000);
past_tense_verb_NTM->voracious = 1;
#line 468 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<preposition>", preposition_NTM, 1, 1000000000);
preposition_NTM->voracious = 1;
#line 489 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<preposition-implying-player>", preposition_implying_player_NTM, 1, 1000000000);
preposition_implying_player_NTM->voracious = 1;
#line 594 "inform7/Chapter 9/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<inequality-conjugations>", inequality_conjugations_NTM);
#line 731 "inform7/Chapter 9/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<comparative-property-construction>", comparative_property_construction_NTM);
#line 737 "inform7/Chapter 9/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<same-property-as-construction>", same_property_as_construction_NTM);
#line 745 "inform7/Chapter 9/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<same-property-as-in-lexicon>", same_property_as_in_lexicon_NTM);
#line 772 "inform7/Chapter 9/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<verb-implies-sentence-subject>", verb_implies_sentence_subject_NTM);
#line 776 "inform7/Chapter 9/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<infinitive-usage>", infinitive_usage_NTM);
#line 780 "inform7/Chapter 9/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<infinitive-usage-exceptional>", infinitive_usage_exceptional_NTM);
#line 789 "inform7/Chapter 9/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<conjugation>", conjugation_NTM);
#line 802 "inform7/Chapter 9/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<participle-like>", participle_like_NTM);
#line 818 "inform7/Chapter 9/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<verb-implies-sentence-object>", verb_implies_sentence_object_NTM);
#line 1362 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<adaptive-verb>", adaptive_verb_NTM, 1, 1000000000);
adaptive_verb_NTM->voracious = 0;
#line 1379 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<auxiliary-verb-only>", auxiliary_verb_only_NTM, 1, 1000000000);
auxiliary_verb_only_NTM->voracious = 0;
#line 1383 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<instance-of-verb>", instance_of_verb_NTM, 1, 1000000000);
instance_of_verb_NTM->voracious = 0;
#line 1400 "inform7/Chapter 9/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 1404 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<modal-verb>", modal_verb_NTM, 1, 1000000000);
modal_verb_NTM->voracious = 0;
#line 1423 "inform7/Chapter 9/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<verb-infinitive>", verb_infinitive_NTM, 1, 1000000000);
verb_infinitive_NTM->voracious = 0;
#line 165 "inform7/Chapter 9/Adjectives.w"
INTERNAL_NONTERMINAL("<adjective-name>", adjective_name_NTM, 1, 1000000000);
adjective_name_NTM->voracious = 0;
#line 1369 "inform7/Chapter 9/Adjectives.w"
INTERNAL_NONTERMINAL("<adaptive-adjective>", adaptive_adjective_NTM, 1, 1000000000);
adaptive_adjective_NTM->voracious = 0;
#line 1488 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<specifies-sentence-subject>", specifies_sentence_subject_NTM);
#line 1494 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-group-list>", literal_pattern_group_list_NTM);
#line 1498 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-group-tail>", literal_pattern_group_tail_NTM);
#line 1502 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-group>", literal_pattern_group_NTM);
#line 1558 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<specifies-sentence-object>", specifies_sentence_object_NTM);
#line 1562 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<kind-specified>", kind_specified_NTM);
#line 1566 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-specification-tail>", literal_pattern_specification_tail_NTM);
#line 1573 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<scaling-instruction>", scaling_instruction_NTM);
#line 1599 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part-list>", literal_pattern_part_list_NTM);
#line 1603 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part-tail>", literal_pattern_part_tail_NTM);
#line 1607 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part>", literal_pattern_part_NTM);
#line 1611 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part-option-list>", literal_pattern_part_option_list_NTM);
#line 1615 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part-option-tail>", literal_pattern_part_option_tail_NTM);
#line 1619 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part-option>", literal_pattern_part_option_NTM);
#line 1903 "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 72 "inform7/Chapter 10/Times of Day.w"
REGISTER_NONTERMINAL("<literal-time>", literal_time_NTM);
#line 77 "inform7/Chapter 10/Times of Day.w"
REGISTER_NONTERMINAL("<elapsed-time>", elapsed_time_NTM);
#line 82 "inform7/Chapter 10/Times of Day.w"
REGISTER_NONTERMINAL("<clock-time>", clock_time_NTM);
#line 86 "inform7/Chapter 10/Times of Day.w"
REGISTER_NONTERMINAL("<am-pm>", am_pm_NTM);
#line 112 "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 140 "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 168 "inform7/Chapter 10/Times of Day.w"
REGISTER_NONTERMINAL("<event-rule-preamble>", event_rule_preamble_NTM);
#line 47 "inform7/Chapter 10/Unicode Translations.w"
REGISTER_NONTERMINAL("<translates-into-unicode-sentence-subject>", translates_into_unicode_sentence_subject_NTM);
#line 57 "inform7/Chapter 10/Unicode Translations.w"
REGISTER_NONTERMINAL("<translates-into-unicode-sentence-object>", translates_into_unicode_sentence_object_NTM);
#line 80 "inform7/Chapter 10/Unicode Translations.w"
REGISTER_NONTERMINAL("<unicode-character>", unicode_character_NTM);
#line 84 "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 11/Nametags.w"
REGISTER_NONTERMINAL("<translates-into-nl-sentence-subject>", translates_into_nl_sentence_subject_NTM);
#line 349 "inform7/Chapter 11/Instances.w"
INTERNAL_NONTERMINAL("<instance-of-object>", instance_of_object_NTM, 1, 1000000000);
instance_of_object_NTM->voracious = 0;
#line 355 "inform7/Chapter 11/Instances.w"
INTERNAL_NONTERMINAL("<instance-of-non-object>", instance_of_non_object_NTM, 1, 1000000000);
instance_of_non_object_NTM->voracious = 0;
#line 364 "inform7/Chapter 11/Instances.w"
INTERNAL_NONTERMINAL("<instance>", instance_NTM, 1, 1000000000);
instance_NTM->voracious = 0;
#line 26 "inform7/Chapter 12/Architecture of the S-Parser.w"
INTERNAL_NONTERMINAL("<s-plain-text>", s_plain_text_NTM, 1, 1000000000);
s_plain_text_NTM->voracious = 0;
#line 49 "inform7/Chapter 12/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 21 "inform7/Chapter 12/Parse Literals.w"
REGISTER_NONTERMINAL("<s-literal>", s_literal_NTM);
#line 48 "inform7/Chapter 12/Parse Literals.w"
REGISTER_NONTERMINAL("<literal>", literal_NTM);
#line 60 "inform7/Chapter 12/Parse Literals.w"
INTERNAL_NONTERMINAL("<literal-unit-notation>", literal_unit_notation_NTM, 1, 1000000000);
literal_unit_notation_NTM->voracious = 0;
#line 77 "inform7/Chapter 12/Parse Literals.w"
REGISTER_NONTERMINAL("<cardinal-number-in-words>", cardinal_number_in_words_NTM);
#line 95 "inform7/Chapter 12/Parse Literals.w"
REGISTER_NONTERMINAL("<ordinal-number-in-words>", ordinal_number_in_words_NTM);
#line 122 "inform7/Chapter 12/Parse Literals.w"
INTERNAL_NONTERMINAL("<cardinal-number>", cardinal_number_NTM, 1, 1);
cardinal_number_NTM->voracious = 0;
#line 131 "inform7/Chapter 12/Parse Literals.w"
INTERNAL_NONTERMINAL("<ordinal-number>", ordinal_number_NTM, 1, 1);
ordinal_number_NTM->voracious = 0;
#line 143 "inform7/Chapter 12/Parse Literals.w"
INTERNAL_NONTERMINAL("<cardinal-number-unlimited>", cardinal_number_unlimited_NTM, 1, 1);
cardinal_number_unlimited_NTM->voracious = 0;
#line 176 "inform7/Chapter 12/Parse Literals.w"
INTERNAL_NONTERMINAL("<quoted-text>", quoted_text_NTM, 1, 1);
quoted_text_NTM->voracious = 0;
#line 183 "inform7/Chapter 12/Parse Literals.w"
INTERNAL_NONTERMINAL("<quoted-text-with-subs>", quoted_text_with_subs_NTM, 1, 1);
quoted_text_with_subs_NTM->voracious = 0;
#line 190 "inform7/Chapter 12/Parse Literals.w"
INTERNAL_NONTERMINAL("<quoted-text-without-subs>", quoted_text_without_subs_NTM, 1, 1);
quoted_text_without_subs_NTM->voracious = 0;
#line 201 "inform7/Chapter 12/Parse Literals.w"
INTERNAL_NONTERMINAL("<empty-text>", empty_text_NTM, 1, 1);
empty_text_NTM->voracious = 0;
#line 212 "inform7/Chapter 12/Parse Literals.w"
INTERNAL_NONTERMINAL("<response-letter>", response_letter_NTM, 1, 1);
response_letter_NTM->voracious = 0;
#line 228 "inform7/Chapter 12/Parse Literals.w"
REGISTER_NONTERMINAL("<literal-truth-state>", literal_truth_state_NTM);
#line 242 "inform7/Chapter 12/Parse Literals.w"
REGISTER_NONTERMINAL("<literal-real-number>", literal_real_number_NTM);
#line 249 "inform7/Chapter 12/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 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-constant-value>", s_constant_value_NTM);
#line 55 "inform7/Chapter 12/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 85 "inform7/Chapter 12/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<spec-named-constant>", spec_named_constant_NTM, 1, 1000000000);
spec_named_constant_NTM->voracious = 0;
#line 102 "inform7/Chapter 12/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 113 "inform7/Chapter 12/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 124 "inform7/Chapter 12/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-rule-name>", s_rule_name_NTM, 1, 1000000000);
s_rule_name_NTM->voracious = 0;
#line 141 "inform7/Chapter 12/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 154 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<property-name-as-noun-phrase>", property_name_as_noun_phrase_NTM);
#line 158 "inform7/Chapter 12/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-property-name>", s_property_name_NTM, 1, 1000000000);
s_property_name_NTM->voracious = 0;
#line 190 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-adjective-list-as-desc>", s_adjective_list_as_desc_NTM);
#line 250 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-adjective-list>", s_adjective_list_NTM);
#line 255 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-adjective-list-unarticled>", s_adjective_list_unarticled_NTM);
#line 265 "inform7/Chapter 12/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-adjective>", s_adjective_NTM, 1, 1000000000);
s_adjective_NTM->voracious = 1;
#line 365 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-qualifiable-noun>", s_qualifiable_noun_NTM);
#line 369 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-qualifiable-common-noun>", s_qualifiable_common_noun_NTM);
#line 376 "inform7/Chapter 12/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-instance-name>", s_instance_name_NTM, 1, 1000000000);
s_instance_name_NTM->voracious = 0;
#line 390 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-applicable-adjective-list>", s_applicable_adjective_list_NTM);
#line 440 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description>", s_description_NTM);
#line 444 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-uncomposite>", s_description_uncomposite_NTM);
#line 448 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-uncalled>", s_description_uncalled_NTM);
#line 456 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-unspecified>", s_description_unspecified_NTM);
#line 460 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-common-description-unspecified>", s_common_description_unspecified_NTM);
#line 468 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-nounless>", s_description_nounless_NTM);
#line 472 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-nounless-uncomposite>", s_description_nounless_uncomposite_NTM);
#line 476 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-nounless-uncalled>", s_description_nounless_uncalled_NTM);
#line 484 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-nounless-unspecified>", s_description_nounless_unspecified_NTM);
#line 548 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-calling-name>", s_calling_name_NTM);
#line 565 "inform7/Chapter 12/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-specifier>", s_specifier_NTM, 1, 1000000000);
s_specifier_NTM->voracious = 1;
#line 582 "inform7/Chapter 12/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-specifying-noun>", s_specifying_noun_NTM, 1, 1000000000);
s_specifying_noun_NTM->voracious = 1;
#line 635 "inform7/Chapter 12/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-nonkind-type>", s_nonkind_type_NTM);
#line 639 "inform7/Chapter 12/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-nonkind-type-unbracketed>", s_nonkind_type_unbracketed_NTM, 1, 1);
s_nonkind_type_unbracketed_NTM->voracious = 0;
#line 61 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-type-expression>", s_type_expression_NTM);
#line 65 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-type-expression-unarticled>", s_type_expression_unarticled_NTM);
#line 87 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-descriptive-type-expression>", s_descriptive_type_expression_NTM);
#line 91 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-descriptive-type-expression-unarticled>", s_descriptive_type_expression_unarticled_NTM);
#line 108 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-variable-scope>", s_variable_scope_NTM);
#line 136 "inform7/Chapter 12/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 146 "inform7/Chapter 12/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<if-pronoun-present>", if_pronoun_present_NTM, 0, 0);
if_pronoun_present_NTM->voracious = 0;
#line 156 "inform7/Chapter 12/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 162 "inform7/Chapter 12/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 219 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-value>", s_value_NTM);
#line 278 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-variable>", s_variable_NTM);
#line 284 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-nonglobal-variable>", s_nonglobal_variable_NTM);
#line 289 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-variable-as-value>", s_variable_as_value_NTM);
#line 295 "inform7/Chapter 12/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<s-local-variable>", s_local_variable_NTM, 1, 1000000000);
s_local_variable_NTM->voracious = 0;
#line 309 "inform7/Chapter 12/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<s-stacked-variable>", s_stacked_variable_NTM, 1, 1000000000);
s_stacked_variable_NTM->voracious = 0;
#line 327 "inform7/Chapter 12/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<s-global-variable>", s_global_variable_NTM, 1, 1000000000);
s_global_variable_NTM->voracious = 0;
#line 338 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<property-of-shape>", property_of_shape_NTM);
#line 350 "inform7/Chapter 12/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 364 "inform7/Chapter 12/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<s-value-phrase>", s_value_phrase_NTM, 1, 1000000000);
s_value_phrase_NTM->voracious = 0;
#line 387 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-table-reference>", s_table_reference_NTM);
#line 399 "inform7/Chapter 12/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-action-pattern-as-value>", s_action_pattern_as_value_NTM);
#line 56 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-sentence>", s_sentence_NTM);
#line 71 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-existential-np>", s_existential_np_NTM);
#line 74 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-existential-verb-tail>", s_existential_verb_tail_NTM);
#line 119 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-general-verb-tail>", s_general_verb_tail_NTM);
#line 137 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-universal-relation-term>", s_universal_relation_term_NTM);
#line 155 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-np-with-relative-clause>", s_np_with_relative_clause_NTM);
#line 159 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-implied-relative-verb-tail>", s_implied_relative_verb_tail_NTM);
#line 163 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-relative-verb-tail>", s_relative_verb_tail_NTM);
#line 272 "inform7/Chapter 12/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 282 "inform7/Chapter 12/Verbal and Relative Clauses.w"
INTERNAL_NONTERMINAL("<if-forced-physical>", if_forced_physical_NTM, 0, 0);
if_forced_physical_NTM->voracious = 0;
#line 293 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-noun-phrase>", s_noun_phrase_NTM);
#line 298 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-noun-phrase-nounless>", s_noun_phrase_nounless_NTM);
#line 307 "inform7/Chapter 12/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-descriptive-np>", s_descriptive_np_NTM);
#line 39 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-condition>", s_condition_NTM);
#line 48 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-condition-pure>", s_condition_pure_NTM);
#line 70 "inform7/Chapter 12/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 115 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-condition-atomic>", s_condition_atomic_NTM);
#line 135 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-nonexistential-phrase-to-decide>", s_nonexistential_phrase_to_decide_NTM);
#line 140 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-existential-phrase-to-decide>", s_existential_phrase_to_decide_NTM);
#line 145 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<existential-verb-phrase>", existential_verb_phrase_NTM);
#line 148 "inform7/Chapter 12/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 158 "inform7/Chapter 12/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 176 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-action-pattern-as-condition>", s_action_pattern_as_condition_NTM);
#line 179 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-action-pattern-as-negated-condition>", s_action_pattern_as_negated_condition_NTM);
#line 185 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-past-action-pattern-as-condition>", s_past_action_pattern_as_condition_NTM);
#line 188 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-past-action-pattern-as-negated-condition>", s_past_action_pattern_as_negated_condition_NTM);
#line 226 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-command>", s_command_NTM);
#line 279 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-command-phrase>", s_command_phrase_NTM);
#line 284 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-command-phrase-inner>", s_command_phrase_inner_NTM);
#line 292 "inform7/Chapter 12/Conditions and Phrases.w"
INTERNAL_NONTERMINAL("<s-to-phrase>", s_to_phrase_NTM, 1, 1000000000);
s_to_phrase_NTM->voracious = 0;
#line 302 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-say-phrase>", s_say_phrase_NTM);
#line 313 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-say-term>", s_say_term_NTM);
#line 317 "inform7/Chapter 12/Conditions and Phrases.w"
INTERNAL_NONTERMINAL("<s-text-substitution>", s_text_substitution_NTM, 1, 1000000000);
s_text_substitution_NTM->voracious = 0;
#line 356 "inform7/Chapter 12/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-unpacked-text-with-substitutions>", s_unpacked_text_with_substitutions_NTM);
#line 631 "inform7/Chapter 15/Kinds.w"
REGISTER_NONTERMINAL("<notable-linguistic-kinds>", notable_linguistic_kinds_NTM);
#line 58 "inform7/Chapter 15/Describing Kinds.w"
INTERNAL_NONTERMINAL("<if-parsing-phrase-tokens>", if_parsing_phrase_tokens_NTM, 0, 0);
if_parsing_phrase_tokens_NTM->voracious = 0;
#line 68 "inform7/Chapter 15/Describing Kinds.w"
INTERNAL_NONTERMINAL("<spec-phrase-token-type>", spec_phrase_token_type_NTM, 1, 1000000000);
spec_phrase_token_type_NTM->voracious = 0;
#line 82 "inform7/Chapter 15/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-kind-for-template>", k_kind_for_template_NTM, 1, 1000000000);
k_kind_for_template_NTM->voracious = 0;
#line 95 "inform7/Chapter 15/Describing Kinds.w"
INTERNAL_NONTERMINAL("<spec-kind-as-name-token>", spec_kind_as_name_token_NTM, 1, 1000000000);
spec_kind_as_name_token_NTM->voracious = 0;
#line 114 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind-as-name-token>", k_kind_as_name_token_NTM);
#line 121 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind-abbreviating>", k_kind_abbreviating_NTM);
#line 129 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind>", k_kind_NTM);
#line 140 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind-articled>", k_kind_articled_NTM);
#line 148 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-variable-definition>", k_variable_definition_NTM);
#line 159 "inform7/Chapter 15/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-base-kind>", k_base_kind_NTM, 1, 1000000000);
k_base_kind_NTM->voracious = 0;
#line 195 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-irregular-kind-construction>", k_irregular_kind_construction_NTM);
#line 210 "inform7/Chapter 15/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-kind-construction>", k_kind_construction_NTM, 1, 1000000000);
k_kind_construction_NTM->voracious = 0;
#line 274 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-single-material>", k_single_material_NTM);
#line 279 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-optional-material>", k_optional_material_NTM);
#line 286 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-tupled-material>", k_tupled_material_NTM);
#line 291 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-tuple-list>", k_tuple_list_NTM);
#line 376 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind-of-kind>", k_kind_of_kind_NTM);
#line 422 "inform7/Chapter 15/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-kind-variable>", k_kind_variable_NTM, 1, 1);
k_kind_variable_NTM->voracious = 0;
#line 436 "inform7/Chapter 15/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-formal-kind-variable>", k_formal_kind_variable_NTM, 1, 1);
k_formal_kind_variable_NTM->voracious = 0;
#line 447 "inform7/Chapter 15/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 459 "inform7/Chapter 15/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind-variable-texts>", k_kind_variable_texts_NTM);
#line 217 "inform7/Chapter 16/Text to Specifications.w"
INTERNAL_NONTERMINAL("<spec-value>", spec_value_NTM, 1, 1000000000);
spec_value_NTM->voracious = 0;
#line 224 "inform7/Chapter 16/Text to Specifications.w"
INTERNAL_NONTERMINAL("<spec-condition>", spec_condition_NTM, 1, 1000000000);
spec_condition_NTM->voracious = 0;
#line 231 "inform7/Chapter 16/Text to Specifications.w"
INTERNAL_NONTERMINAL("<spec-command>", spec_command_NTM, 1, 1000000000);
spec_command_NTM->voracious = 0;
#line 238 "inform7/Chapter 16/Text to Specifications.w"
INTERNAL_NONTERMINAL("<spec-type-expression>", spec_type_expression_NTM, 1, 1000000000);
spec_type_expression_NTM->voracious = 0;
#line 245 "inform7/Chapter 16/Text to Specifications.w"
INTERNAL_NONTERMINAL("<spec-descriptive-type-expression>", spec_descriptive_type_expression_NTM, 1, 1000000000);
spec_descriptive_type_expression_NTM->voracious = 0;
#line 257 "inform7/Chapter 16/Text to Specifications.w"
REGISTER_NONTERMINAL("<spec-type-expression-or-value>", spec_type_expression_or_value_NTM);
#line 265 "inform7/Chapter 16/Text to Specifications.w"
REGISTER_NONTERMINAL("<spec-global-variable>", spec_global_variable_NTM);
#line 279 "inform7/Chapter 16/Text to Specifications.w"
REGISTER_NONTERMINAL("<spec-kind>", spec_kind_NTM);
#line 293 "inform7/Chapter 16/Text to Specifications.w"
REGISTER_NONTERMINAL("<spec-description>", spec_description_NTM);
#line 299 "inform7/Chapter 16/Text to Specifications.w"
REGISTER_NONTERMINAL("<spec-instance>", spec_instance_NTM);
#line 305 "inform7/Chapter 16/Text to Specifications.w"
REGISTER_NONTERMINAL("<spec-table-name>", spec_table_name_NTM);
#line 313 "inform7/Chapter 16/Text to Specifications.w"
INTERNAL_NONTERMINAL("<spec-stored-action>", spec_stored_action_NTM, 1, 1000000000);
spec_stored_action_NTM->voracious = 0;
#line 67 "inform7/Chapter 16/STORAGE Specifications.w"
REGISTER_NONTERMINAL("<storage-nonkind-types>", storage_nonkind_types_NTM);
#line 158 "inform7/Chapter 16/CONDITION Specifications.w"
REGISTER_NONTERMINAL("<condition-nonkind-types>", condition_nonkind_types_NTM);
#line 68 "inform7/Chapter 16/COMMAND Specifications.w"
REGISTER_NONTERMINAL("<command-phrase-nonkind-types>", command_phrase_nonkind_types_NTM);
#line 629 "inform7/Chapter 16/Type Checking.w"
REGISTER_NONTERMINAL("<structural-phrase-problem-diagnosis>", structural_phrase_problem_diagnosis_NTM);
#line 741 "inform7/Chapter 16/Type Checking.w"
REGISTER_NONTERMINAL("<unknown-text-shape>", unknown_text_shape_NTM);
#line 746 "inform7/Chapter 16/Type Checking.w"
REGISTER_NONTERMINAL("<unknown-text-substitution-problem-diagnosis>", unknown_text_substitution_problem_diagnosis_NTM);
#line 869 "inform7/Chapter 16/Type Checking.w"
REGISTER_NONTERMINAL("<unknown-value-problem-diagnosis>", unknown_value_problem_diagnosis_NTM);
#line 876 "inform7/Chapter 16/Type Checking.w"
REGISTER_NONTERMINAL("<unknown-use-option-diagnosis>", unknown_use_option_diagnosis_NTM);
#line 880 "inform7/Chapter 16/Type Checking.w"
REGISTER_NONTERMINAL("<unknown-activity-diagnosis>", unknown_activity_diagnosis_NTM);
#line 3245 "inform7/Chapter 16/Type Checking.w"
REGISTER_NONTERMINAL("<failed-text-substitution-diagnosis>", failed_text_substitution_diagnosis_NTM);
#line 3359 "inform7/Chapter 16/Type Checking.w"
REGISTER_NONTERMINAL("<condition-problem-diagnosis>", condition_problem_diagnosis_NTM);
#line 3363 "inform7/Chapter 16/Type Checking.w"
REGISTER_NONTERMINAL("<condition-problem-part-tail>", condition_problem_part_tail_NTM);
#line 3367 "inform7/Chapter 16/Type Checking.w"
REGISTER_NONTERMINAL("<condition-problem-part>", condition_problem_part_NTM);
#line 230 "inform7/Chapter 17/Properties.w"
REGISTER_NONTERMINAL("<notable-properties>", notable_properties_NTM);
#line 271 "inform7/Chapter 17/Properties.w"
REGISTER_NONTERMINAL("<property-name-construction>", property_name_construction_NTM);
#line 313 "inform7/Chapter 17/Properties.w"
INTERNAL_NONTERMINAL("<property-name>", property_name_NTM, 1, 1000000000);
property_name_NTM->voracious = 0;
#line 329 "inform7/Chapter 17/Properties.w"
INTERNAL_NONTERMINAL("<either-or-property-name>", either_or_property_name_NTM, 1, 1000000000);
either_or_property_name_NTM->voracious = 0;
#line 343 "inform7/Chapter 17/Properties.w"
INTERNAL_NONTERMINAL("<value-property-name>", value_property_name_NTM, 1, 1000000000);
value_property_name_NTM->voracious = 0;
#line 361 "inform7/Chapter 17/Properties.w"
INTERNAL_NONTERMINAL("<property-name-v>", property_name_v_NTM, 1, 1000000000);
property_name_v_NTM->voracious = 1;
#line 379 "inform7/Chapter 17/Properties.w"
REGISTER_NONTERMINAL("<name-looking-like-property-test>", name_looking_like_property_test_NTM);
#line 386 "inform7/Chapter 17/Properties.w"
INTERNAL_NONTERMINAL("<ambiguous-property-name>", ambiguous_property_name_NTM, 1, 1000000000);
ambiguous_property_name_NTM->voracious = 1;
#line 232 "inform7/Chapter 17/Measurement Adjectives.w"
REGISTER_NONTERMINAL("<measurement-adjective-definition>", measurement_adjective_definition_NTM);
#line 237 "inform7/Chapter 17/Measurement Adjectives.w"
REGISTER_NONTERMINAL("<measurement-range>", measurement_range_NTM);
#line 79 "inform7/Chapter 17/Value-Property Relations.w"
REGISTER_NONTERMINAL("<relation-property-name>", relation_property_name_NTM);
#line 50 "inform7/Chapter 18/The Naming Thicket.w"
REGISTER_NONTERMINAL("<notable-naming-properties>", notable_naming_properties_NTM);
#line 237 "inform7/Chapter 19/Spatial Model.w"
REGISTER_NONTERMINAL("<notable-spatial-kinds>", notable_spatial_kinds_NTM);
#line 335 "inform7/Chapter 19/Spatial Model.w"
REGISTER_NONTERMINAL("<notable-spatial-properties>", notable_spatial_properties_NTM);
#line 409 "inform7/Chapter 19/Spatial Model.w"
REGISTER_NONTERMINAL("<spatial-specifying-nouns>", spatial_specifying_nouns_NTM);
#line 454 "inform7/Chapter 19/Spatial Model.w"
REGISTER_NONTERMINAL("<notable-spatial-noun-phrases>", notable_spatial_noun_phrases_NTM);
#line 52 "inform7/Chapter 19/The Player.w"
REGISTER_NONTERMINAL("<notable-player-instances>", notable_player_instances_NTM);
#line 93 "inform7/Chapter 19/The Player.w"
REGISTER_NONTERMINAL("<notable-player-variables>", notable_player_variables_NTM);
#line 246 "inform7/Chapter 19/The Player.w"
REGISTER_NONTERMINAL("<implicit-player-relationship>", implicit_player_relationship_NTM);
#line 42 "inform7/Chapter 19/Backdrops.w"
REGISTER_NONTERMINAL("<notable-backdrops-kinds>", notable_backdrops_kinds_NTM);
#line 70 "inform7/Chapter 19/Backdrops.w"
REGISTER_NONTERMINAL("<notable-backdrops-properties>", notable_backdrops_properties_NTM);
#line 178 "inform7/Chapter 19/Backdrops.w"
REGISTER_NONTERMINAL("<notable-backdrops-noun-phrases>", notable_backdrops_noun_phrases_NTM);
#line 71 "inform7/Chapter 19/Regions.w"
REGISTER_NONTERMINAL("<notable-regions-kinds>", notable_regions_kinds_NTM);
#line 139 "inform7/Chapter 19/Regions.w"
REGISTER_NONTERMINAL("<notable-regions-properties>", notable_regions_properties_NTM);
#line 171 "inform7/Chapter 19/The Map.w"
REGISTER_NONTERMINAL("<notable-map-kinds>", notable_map_kinds_NTM);
#line 256 "inform7/Chapter 19/The Map.w"
REGISTER_NONTERMINAL("<notable-map-directions>", notable_map_directions_NTM);
#line 427 "inform7/Chapter 19/The Map.w"
REGISTER_NONTERMINAL("<notable-map-properties>", notable_map_properties_NTM);
#line 508 "inform7/Chapter 19/The Map.w"
REGISTER_NONTERMINAL("<notable-map-noun-phrases>", notable_map_noun_phrases_NTM);
#line 91 "inform7/Chapter 19/Map Connection Relations.w"
REGISTER_NONTERMINAL("<mapping-relation-construction>", mapping_relation_construction_NTM);
#line 94 "inform7/Chapter 19/Map Connection Relations.w"
REGISTER_NONTERMINAL("<mapping-preposition-construction>", mapping_preposition_construction_NTM);
#line 103 "inform7/Chapter 19/Map Connection Relations.w"
REGISTER_NONTERMINAL("<notable-directions>", notable_directions_NTM);
#line 999 "inform7/Chapter 19/HTML Map.w"
REGISTER_NONTERMINAL("<map-name-abbreviation-omission-words>", map_name_abbreviation_omission_words_NTM);
#line 303 "inform7/Chapter 19/EPS Map.w"
REGISTER_NONTERMINAL("<direction-name>", direction_name_NTM);
#line 315 "inform7/Chapter 19/EPS Map.w"
REGISTER_NONTERMINAL("<index-map-sentence-subject>", index_map_sentence_subject_NTM);
#line 327 "inform7/Chapter 19/EPS Map.w"
REGISTER_NONTERMINAL("<map-positioning>", map_positioning_NTM);
#line 387 "inform7/Chapter 19/EPS Map.w"
REGISTER_NONTERMINAL("<map-setting>", map_setting_NTM);
#line 392 "inform7/Chapter 19/EPS Map.w"
REGISTER_NONTERMINAL("<map-setting-scope>", map_setting_scope_NTM);
#line 396 "inform7/Chapter 19/EPS Map.w"
REGISTER_NONTERMINAL("<map-setting-scope-unarticled>", map_setting_scope_unarticled_NTM);
#line 410 "inform7/Chapter 19/EPS Map.w"
INTERNAL_NONTERMINAL("<map-parameter>", map_parameter_NTM, 1, 1000000000);
map_parameter_NTM->voracious = 0;
#line 439 "inform7/Chapter 19/EPS Map.w"
REGISTER_NONTERMINAL("<map-setting-value>", map_setting_value_NTM);
#line 446 "inform7/Chapter 19/EPS Map.w"
REGISTER_NONTERMINAL("<map-setting-boolean>", map_setting_boolean_NTM);
#line 456 "inform7/Chapter 19/EPS Map.w"
INTERNAL_NONTERMINAL("<map-offset>", map_offset_NTM, 1, 1);
map_offset_NTM->voracious = 0;
#line 466 "inform7/Chapter 19/EPS Map.w"
REGISTER_NONTERMINAL("<map-rubric>", map_rubric_NTM);
#line 121 "inform7/Chapter 19/Scenes.w"
REGISTER_NONTERMINAL("<notable-scene-properties>", notable_scene_properties_NTM);
#line 179 "inform7/Chapter 19/Scenes.w"
REGISTER_NONTERMINAL("<notable-scenes>", notable_scenes_NTM);
#line 342 "inform7/Chapter 19/Scenes.w"
REGISTER_NONTERMINAL("<scene-ends-sentence-subject>", scene_ends_sentence_subject_NTM);
#line 359 "inform7/Chapter 19/Scenes.w"
REGISTER_NONTERMINAL("<scene-ends-sentence-adverb>", scene_ends_sentence_adverb_NTM);
#line 367 "inform7/Chapter 19/Scenes.w"
REGISTER_NONTERMINAL("<scene-ends-sentence-object>", scene_ends_sentence_object_NTM);
#line 411 "inform7/Chapter 19/Scenes.w"
REGISTER_NONTERMINAL("<scene-name>", scene_name_NTM);
#line 415 "inform7/Chapter 19/Scenes.w"
REGISTER_NONTERMINAL("<scene-name-unarticled>", scene_name_unarticled_NTM);
#line 431 "inform7/Chapter 19/Scenes.w"
INTERNAL_NONTERMINAL("<scene-end-name>", scene_end_name_NTM, 1, 1000000000);
scene_end_name_NTM->voracious = 0;
#line 437 "inform7/Chapter 19/Scenes.w"
INTERNAL_NONTERMINAL("<scene-end-name-creating>", scene_end_name_creating_NTM, 1, 1000000000);
scene_end_name_creating_NTM->voracious = 0;
#line 864 "inform7/Chapter 19/Scenes.w"
REGISTER_NONTERMINAL("<spec-scene-description>", spec_scene_description_NTM);
#line 62 "inform7/Chapter 20/Nonlocal Variables.w"
REGISTER_NONTERMINAL("<notable-variables>", notable_variables_NTM);
#line 629 "inform7/Chapter 20/Nonlocal Variables.w"
REGISTER_NONTERMINAL("<value-understood-variable-name>", value_understood_variable_name_NTM);
#line 52 "inform7/Chapter 20/Bibliographic Data.w"
REGISTER_NONTERMINAL("<notable-bibliographic-variables>", notable_bibliographic_variables_NTM);
#line 92 "inform7/Chapter 20/Bibliographic Data.w"
REGISTER_NONTERMINAL("<titling-line>", titling_line_NTM);
#line 96 "inform7/Chapter 20/Bibliographic Data.w"
REGISTER_NONTERMINAL("<plain-titling-line>", plain_titling_line_NTM);
#line 214 "inform7/Chapter 20/Bibliographic Data.w"
REGISTER_NONTERMINAL("<episode-sentence-object>", episode_sentence_object_NTM);
#line 65 "inform7/Chapter 20/Release Instructions.w"
REGISTER_NONTERMINAL("<release-sentence-object>", release_sentence_object_NTM);
#line 103 "inform7/Chapter 20/Release Instructions.w"
REGISTER_NONTERMINAL("<privacy-indicator>", privacy_indicator_NTM);
#line 107 "inform7/Chapter 20/Release Instructions.w"
REGISTER_NONTERMINAL("<exposed-innards>", exposed_innards_NTM);
#line 60 "inform7/Chapter 20/List Constants.w"
REGISTER_NONTERMINAL("<literal-list>", literal_list_NTM);
#line 64 "inform7/Chapter 20/List Constants.w"
REGISTER_NONTERMINAL("<literal-list-contents>", literal_list_contents_NTM);
#line 68 "inform7/Chapter 20/List Constants.w"
REGISTER_NONTERMINAL("<literal-list-entry>", literal_list_entry_NTM);
#line 223 "inform7/Chapter 20/Table Columns.w"
REGISTER_NONTERMINAL("<table-column-heading>", table_column_heading_NTM);
#line 230 "inform7/Chapter 20/Table Columns.w"
REGISTER_NONTERMINAL("<table-column-heading-unbracketed>", table_column_heading_unbracketed_NTM);
#line 272 "inform7/Chapter 20/Table Columns.w"
REGISTER_NONTERMINAL("<table-column-name-construction>", table_column_name_construction_NTM);
#line 249 "inform7/Chapter 20/Tables.w"
REGISTER_NONTERMINAL("<table-header>", table_header_NTM);
#line 255 "inform7/Chapter 20/Tables.w"
REGISTER_NONTERMINAL("<table-new-name>", table_new_name_NTM);
#line 277 "inform7/Chapter 20/Tables.w"
REGISTER_NONTERMINAL("<table-names-construction>", table_names_construction_NTM);
#line 287 "inform7/Chapter 20/Tables.w"
REGISTER_NONTERMINAL("<table-footer>", table_footer_NTM);
#line 862 "inform7/Chapter 20/Tables.w"
REGISTER_NONTERMINAL("<table-cell>", table_cell_NTM);
#line 871 "inform7/Chapter 20/Tables.w"
REGISTER_NONTERMINAL("<table-cell-blank>", table_cell_blank_NTM);
#line 874 "inform7/Chapter 20/Tables.w"
REGISTER_NONTERMINAL("<table-cell-value>", table_cell_value_NTM);
#line 880 "inform7/Chapter 20/Tables.w"
REGISTER_NONTERMINAL("<list-of-double-quotes>", list_of_double_quotes_NTM);
#line 308 "inform7/Chapter 20/Runtime Support for Tables.w"
REGISTER_NONTERMINAL("<rankings-table-name>", rankings_table_name_NTM);
#line 31 "inform7/Chapter 20/Tables of Definitions.w"
REGISTER_NONTERMINAL("<defined-by-sentence-subject>", defined_by_sentence_subject_NTM);
#line 64 "inform7/Chapter 20/Tables of Definitions.w"
REGISTER_NONTERMINAL("<defined-by-sentence-object>", defined_by_sentence_object_NTM);
#line 368 "inform7/Chapter 20/Tables of Definitions.w"
REGISTER_NONTERMINAL("<unfortunate-table-column-property>", unfortunate_table_column_property_NTM);
#line 142 "inform7/Chapter 21/Equations.w"
REGISTER_NONTERMINAL("<equation-name>", equation_name_NTM);
#line 239 "inform7/Chapter 21/Equations.w"
REGISTER_NONTERMINAL("<equation-names-construction>", equation_names_construction_NTM);
#line 322 "inform7/Chapter 21/Equations.w"
REGISTER_NONTERMINAL("<equation-where>", equation_where_NTM);
#line 381 "inform7/Chapter 21/Equations.w"
REGISTER_NONTERMINAL("<equation-where-list>", equation_where_list_NTM);
#line 386 "inform7/Chapter 21/Equations.w"
REGISTER_NONTERMINAL("<equation-where-tail>", equation_where_tail_NTM);
#line 390 "inform7/Chapter 21/Equations.w"
REGISTER_NONTERMINAL("<equation-where-setting-entry>", equation_where_setting_entry_NTM);
#line 393 "inform7/Chapter 21/Equations.w"
REGISTER_NONTERMINAL("<equation-where-setting>", equation_where_setting_NTM);
#line 402 "inform7/Chapter 21/Equations.w"
REGISTER_NONTERMINAL("<equation-symbol>", equation_symbol_NTM);
#line 640 "inform7/Chapter 21/Equations.w"
INTERNAL_NONTERMINAL("<valid-equation-symbol>", valid_equation_symbol_NTM, 1, 1000000000);
valid_equation_symbol_NTM->voracious = 0;
#line 110 "inform7/Chapter 21/Inform 6 Inclusions.w"
REGISTER_NONTERMINAL("<inform6-inclusion-location>", inform6_inclusion_location_NTM);
#line 118 "inform7/Chapter 21/Inform 6 Inclusions.w"
REGISTER_NONTERMINAL("<inclusion-side>", inclusion_side_NTM);
#line 288 "inform7/Chapter 21/Inform 6 Inclusions.w"
REGISTER_NONTERMINAL("<use-translates-as-sentence-object>", use_translates_as_sentence_object_NTM);
#line 323 "inform7/Chapter 21/Inform 6 Inclusions.w"
REGISTER_NONTERMINAL("<use-sentence-object>", use_sentence_object_NTM);
#line 334 "inform7/Chapter 21/Inform 6 Inclusions.w"
REGISTER_NONTERMINAL("<notable-use-option-name>", notable_use_option_name_NTM);
#line 460 "inform7/Chapter 21/Inform 6 Inclusions.w"
REGISTER_NONTERMINAL("<immediate-use>", immediate_use_NTM);
#line 465 "inform7/Chapter 21/Inform 6 Inclusions.w"
REGISTER_NONTERMINAL("<immediate-use-tail>", immediate_use_tail_NTM);
#line 469 "inform7/Chapter 21/Inform 6 Inclusions.w"
REGISTER_NONTERMINAL("<immediate-use-entry>", immediate_use_entry_NTM);
#line 307 "inform7/Chapter 22/Phrases.w"
REGISTER_NONTERMINAL("<inline-phrase-definition>", inline_phrase_definition_NTM);
#line 132 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<rule-preamble>", rule_preamble_NTM);
#line 186 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<now-phrase-preamble>", now_phrase_preamble_NTM);
#line 196 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<rule-preamble-fine>", rule_preamble_fine_NTM);
#line 200 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<rule-preamble-finer>", rule_preamble_finer_NTM);
#line 205 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<rulebook-stem-embellished>", rulebook_stem_embellished_NTM);
#line 420 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<unrecognised-rule-stem-diagnosis>", unrecognised_rule_stem_diagnosis_NTM);
#line 508 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<when-while-clause>", when_while_clause_NTM);
#line 897 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<parametric-problem-diagnosis>", parametric_problem_diagnosis_NTM);
#line 924 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<action-problem-diagnosis>", action_problem_diagnosis_NTM);
#line 962 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<action-when-diagnosis>", action_when_diagnosis_NTM);
#line 972 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<anl-diagnosis>", anl_diagnosis_NTM);
#line 976 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<anl-inner-diagnosis>", anl_inner_diagnosis_NTM);
#line 980 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<anl-tail-diagnosis>", anl_tail_diagnosis_NTM);
#line 984 "inform7/Chapter 22/Phrase Usage.w"
REGISTER_NONTERMINAL("<anl-entry-diagnosis>", anl_entry_diagnosis_NTM);
#line 430 "inform7/Chapter 22/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<phrase-preamble>", phrase_preamble_NTM);
#line 435 "inform7/Chapter 22/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<to-preamble>", to_preamble_NTM);
#line 451 "inform7/Chapter 22/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<say-preamble>", say_preamble_NTM);
#line 476 "inform7/Chapter 22/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<to-return-data>", to_return_data_NTM);
#line 485 "inform7/Chapter 22/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<return-kind>", return_kind_NTM);
#line 599 "inform7/Chapter 22/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<phrase-definition-word-or-token>", phrase_definition_word_or_token_NTM);
#line 610 "inform7/Chapter 22/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<phrase-token-declaration>", phrase_token_declaration_NTM);
#line 137 "inform7/Chapter 22/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-declaration-list>", phrase_option_declaration_list_NTM);
#line 142 "inform7/Chapter 22/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-declaration-tail>", phrase_option_declaration_tail_NTM);
#line 148 "inform7/Chapter 22/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-declaration-setting-entry>", phrase_option_declaration_setting_entry_NTM);
#line 255 "inform7/Chapter 22/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-list>", phrase_option_list_NTM);
#line 260 "inform7/Chapter 22/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-tail>", phrase_option_tail_NTM);
#line 264 "inform7/Chapter 22/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-setting-entry>", phrase_option_setting_entry_NTM);
#line 296 "inform7/Chapter 22/Phrase Options.w"
INTERNAL_NONTERMINAL("<phrase-option>", phrase_option_NTM, 1, 1000000000);
phrase_option_NTM->voracious = 0;
#line 632 "inform7/Chapter 22/Local Variables.w"
REGISTER_NONTERMINAL("<new-called-name>", new_called_name_NTM);
#line 637 "inform7/Chapter 22/Local Variables.w"
REGISTER_NONTERMINAL("<new-called-name-unarticled>", new_called_name_unarticled_NTM);
#line 642 "inform7/Chapter 22/Local Variables.w"
INTERNAL_NONTERMINAL("<existing-local-name>", existing_local_name_NTM, 1, 1000000000);
existing_local_name_NTM->voracious = 0;
#line 16 "inform7/Chapter 22/Parse Invocations.w"
REGISTER_NONTERMINAL("<end-phrase-construction>", end_phrase_construction_NTM);
#line 373 "inform7/Chapter 22/Compile Invocations Inline.w"
REGISTER_NONTERMINAL("<inline-substitution>", inline_substitution_NTM);
#line 382 "inform7/Chapter 22/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 135 "inform7/Chapter 22/Phrasebook Index.w"
REGISTER_NONTERMINAL("<heading-with-parenthesis>", heading_with_parenthesis_NTM);
#line 140 "inform7/Chapter 22/Phrasebook Index.w"
REGISTER_NONTERMINAL("<heading-name-hyphenated>", heading_name_hyphenated_NTM);
#line 52 "inform7/Chapter 22/Adjectival Definitions.w"
REGISTER_NONTERMINAL("<definition-header>", definition_header_NTM);
#line 85 "inform7/Chapter 22/Adjectival Definitions.w"
REGISTER_NONTERMINAL("<adjective-definition>", adjective_definition_NTM);
#line 90 "inform7/Chapter 22/Adjectival Definitions.w"
REGISTER_NONTERMINAL("<adjective-domain>", adjective_domain_NTM);
#line 95 "inform7/Chapter 22/Adjectival Definitions.w"
REGISTER_NONTERMINAL("<adjective-wording>", adjective_wording_NTM);
#line 343 "inform7/Chapter 22/Adjectival Definitions.w"
REGISTER_NONTERMINAL("<inform6-routine-adjective-definition>", inform6_routine_adjective_definition_NTM);
#line 409 "inform7/Chapter 22/Adjectival Definitions.w"
REGISTER_NONTERMINAL("<inform6-condition-adjective-definition>", inform6_condition_adjective_definition_NTM);
#line 160 "inform7/Chapter 23/Rulebooks.w"
REGISTER_NONTERMINAL("<new-rulebook-name>", new_rulebook_name_NTM);
#line 209 "inform7/Chapter 23/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-name-construction>", rulebook_name_construction_NTM);
#line 407 "inform7/Chapter 23/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-variable-name>", rulebook_variable_name_NTM);
#line 593 "inform7/Chapter 23/Rulebooks.w"
INTERNAL_NONTERMINAL("<rulebook-stem>", rulebook_stem_NTM, 1, 1000000000);
rulebook_stem_NTM->voracious = 1;
#line 621 "inform7/Chapter 23/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-stem-inner>", rulebook_stem_inner_NTM);
#line 626 "inform7/Chapter 23/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-stem-inner-unarticled>", rulebook_stem_inner_unarticled_NTM);
#line 633 "inform7/Chapter 23/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-stem-name>", rulebook_stem_name_NTM);
#line 863 "inform7/Chapter 23/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-property>", rulebook_property_NTM);
#line 110 "inform7/Chapter 23/Focus and Outcome.w"
REGISTER_NONTERMINAL("<rulebook-default-outcome>", rulebook_default_outcome_NTM);
#line 114 "inform7/Chapter 23/Focus and Outcome.w"
REGISTER_NONTERMINAL("<rule-outcome>", rule_outcome_NTM);
#line 153 "inform7/Chapter 23/Focus and Outcome.w"
REGISTER_NONTERMINAL("<rulebook-outcome-list>", rulebook_outcome_list_NTM);
#line 158 "inform7/Chapter 23/Focus and Outcome.w"
REGISTER_NONTERMINAL("<rulebook-outcome-tail>", rulebook_outcome_tail_NTM);
#line 162 "inform7/Chapter 23/Focus and Outcome.w"
REGISTER_NONTERMINAL("<rulebook-outcome-setting-entry>", rulebook_outcome_setting_entry_NTM);
#line 165 "inform7/Chapter 23/Focus and Outcome.w"
REGISTER_NONTERMINAL("<form-of-named-rule-outcome>", form_of_named_rule_outcome_NTM);
#line 28 "inform7/Chapter 23/Rule Placement Sentences.w"
INTERNAL_NONTERMINAL("<rulebook-name>", rulebook_name_NTM, 1, 1000000000);
rulebook_name_NTM->voracious = 0;
#line 40 "inform7/Chapter 23/Rule Placement Sentences.w"
INTERNAL_NONTERMINAL("<rule-name>", rule_name_NTM, 1, 1000000000);
rule_name_NTM->voracious = 0;
#line 63 "inform7/Chapter 23/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<substitutes-for-sentence-subject>", substitutes_for_sentence_subject_NTM);
#line 67 "inform7/Chapter 23/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<substitutes-for-sentence-object>", substitutes_for_sentence_object_NTM);
#line 108 "inform7/Chapter 23/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<does-nothing-sentence-subject>", does_nothing_sentence_subject_NTM);
#line 143 "inform7/Chapter 23/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<listed-in-sentence-subject>", listed_in_sentence_subject_NTM);
#line 150 "inform7/Chapter 23/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<listed-in-sentence-object>", listed_in_sentence_object_NTM);
#line 163 "inform7/Chapter 23/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<offset-rule>", offset_rule_NTM);
#line 167 "inform7/Chapter 23/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<destination-rulebook>", destination_rulebook_NTM);
#line 187 "inform7/Chapter 24/Chronology.w"
REGISTER_NONTERMINAL("<historical-reference-possible>", historical_reference_possible_NTM);
#line 193 "inform7/Chapter 24/Chronology.w"
REGISTER_NONTERMINAL("<historical-reference>", historical_reference_NTM);
#line 197 "inform7/Chapter 24/Chronology.w"
REGISTER_NONTERMINAL("<repetition-specification>", repetition_specification_NTM);
#line 207 "inform7/Chapter 24/Chronology.w"
REGISTER_NONTERMINAL("<repetitions>", repetitions_NTM);
#line 211 "inform7/Chapter 24/Chronology.w"
REGISTER_NONTERMINAL("<iteration-repetitions>", iteration_repetitions_NTM);
#line 218 "inform7/Chapter 24/Chronology.w"
REGISTER_NONTERMINAL("<turn-repetitions>", turn_repetitions_NTM);
#line 222 "inform7/Chapter 24/Chronology.w"
REGISTER_NONTERMINAL("<rep-number>", rep_number_NTM);
#line 245 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<notable-actions>", notable_actions_NTM);
#line 252 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-name-construction>", action_name_construction_NTM);
#line 353 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-pronoun>", action_pronoun_NTM);
#line 380 "inform7/Chapter 24/Actions.w"
INTERNAL_NONTERMINAL("<action-name>", action_name_NTM, 1, 1000000000);
action_name_NTM->voracious = 0;
#line 408 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-optional-trailing-prepositions>", action_optional_trailing_prepositions_NTM);
#line 520 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-variable>", action_variable_NTM);
#line 528 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-variable-name>", action_variable_name_NTM);
#line 730 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-sentence-subject>", action_sentence_subject_NTM);
#line 758 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-clause>", action_clause_NTM);
#line 765 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-applications>", action_applications_NTM);
#line 776 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<act-req>", act_req_NTM);
#line 780 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-access>", action_access_NTM);
#line 788 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-sentence-object>", action_sentence_object_NTM);
#line 792 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-clauses>", action_clauses_NTM);
#line 797 "inform7/Chapter 24/Actions.w"
REGISTER_NONTERMINAL("<action-clause-terminated>", action_clause_terminated_NTM);
#line 105 "inform7/Chapter 24/Action Name Lists.w"
REGISTER_NONTERMINAL("<action-list>", action_list_NTM);
#line 113 "inform7/Chapter 24/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-excluded>", anl_excluded_NTM);
#line 137 "inform7/Chapter 24/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-to-tail>", anl_to_tail_NTM);
#line 141 "inform7/Chapter 24/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-operand>", anl_operand_NTM);
#line 144 "inform7/Chapter 24/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-in-tail>", anl_in_tail_NTM);
#line 176 "inform7/Chapter 24/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl>", anl_NTM);
#line 180 "inform7/Chapter 24/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-tail>", anl_tail_NTM);
#line 195 "inform7/Chapter 24/Action Name Lists.w"
INTERNAL_NONTERMINAL("<anl-entry>", anl_entry_NTM, 1, 1000000000);
anl_entry_NTM->voracious = 0;
#line 593 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pattern>", action_pattern_NTM);
#line 607 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<we-are-action-pattern>", we_are_action_pattern_NTM);
#line 618 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pattern-negated>", action_pattern_negated_NTM);
#line 629 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pattern-past>", action_pattern_past_NTM);
#line 637 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pattern-past-negated>", action_pattern_past_negated_NTM);
#line 658 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pattern-core-actor>", action_pattern_core_actor_NTM);
#line 677 "inform7/Chapter 24/Action Patterns.w"
INTERNAL_NONTERMINAL("<actor-description>", actor_description_NTM, 1, 1000000000);
actor_description_NTM->voracious = 1;
#line 741 "inform7/Chapter 24/Action Patterns.w"
INTERNAL_NONTERMINAL("<action-pattern-core>", action_pattern_core_NTM, 1, 1000000000);
action_pattern_core_NTM->voracious = 0;
#line 748 "inform7/Chapter 24/Action Patterns.w"
INTERNAL_NONTERMINAL("<action-pattern-past-core>", action_pattern_past_core_NTM, 1, 1000000000);
action_pattern_past_core_NTM->voracious = 0;
#line 765 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pronominal>", action_pronominal_NTM);
#line 814 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<ap-common-core>", ap_common_core_NTM);
#line 825 "inform7/Chapter 24/Action Patterns.w"
INTERNAL_NONTERMINAL("<condition-in-ap>", condition_in_ap_NTM, 1, 1000000000);
condition_in_ap_NTM->voracious = 0;
#line 847 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<ap-common-core-inner>", ap_common_core_inner_NTM);
#line 862 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<ap-common-core-inner-inner>", ap_common_core_inner_inner_NTM);
#line 868 "inform7/Chapter 24/Action Patterns.w"
INTERNAL_NONTERMINAL("<named-action-pattern>", named_action_pattern_NTM, 1, 1000000000);
named_action_pattern_NTM->voracious = 0;
#line 915 "inform7/Chapter 24/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 939 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<action-operand>", action_operand_NTM);
#line 944 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<going-action-irregular-operand>", going_action_irregular_operand_NTM);
#line 948 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<understanding-action-irregular-operand>", understanding_action_irregular_operand_NTM);
#line 956 "inform7/Chapter 24/Action Patterns.w"
REGISTER_NONTERMINAL("<action-parameter>", action_parameter_NTM);
#line 965 "inform7/Chapter 24/Action Patterns.w"
INTERNAL_NONTERMINAL("<spec-local-variable>", spec_local_variable_NTM, 1, 1000000000);
spec_local_variable_NTM->voracious = 0;
#line 117 "inform7/Chapter 24/Activities.w"
REGISTER_NONTERMINAL("<activity-sentence-subject>", activity_sentence_subject_NTM);
#line 122 "inform7/Chapter 24/Activities.w"
REGISTER_NONTERMINAL("<activity-noted>", activity_noted_NTM);
#line 127 "inform7/Chapter 24/Activities.w"
REGISTER_NONTERMINAL("<activity-new-name>", activity_new_name_NTM);
#line 136 "inform7/Chapter 24/Activities.w"
REGISTER_NONTERMINAL("<activity-name-construction>", activity_name_construction_NTM);
#line 259 "inform7/Chapter 24/Activities.w"
REGISTER_NONTERMINAL("<activity-variable-name>", activity_variable_name_NTM);
#line 451 "inform7/Chapter 24/Activities.w"
REGISTER_NONTERMINAL("<run-time-context>", run_time_context_NTM);
#line 455 "inform7/Chapter 24/Activities.w"
REGISTER_NONTERMINAL("<activity-list-unnegated>", activity_list_unnegated_NTM);
#line 460 "inform7/Chapter 24/Activities.w"
REGISTER_NONTERMINAL("<activity-tail>", activity_tail_NTM);
#line 464 "inform7/Chapter 24/Activities.w"
REGISTER_NONTERMINAL("<activity-list-entry>", activity_list_entry_NTM);
#line 480 "inform7/Chapter 24/Activities.w"
REGISTER_NONTERMINAL("<activity-operand>", activity_operand_NTM);
#line 551 "inform7/Chapter 24/Activities.w"
INTERNAL_NONTERMINAL("<activity-name>", activity_name_NTM, 1, 1000000000);
activity_name_NTM->voracious = 0;
#line 578 "inform7/Chapter 24/Activities.w"
INTERNAL_NONTERMINAL("<if-parsing-al-conditions>", if_parsing_al_conditions_NTM, 0, 0);
if_parsing_al_conditions_NTM->voracious = 0;
#line 138 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-sentence-subject>", understand_sentence_subject_NTM);
#line 160 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-regular-list>", understand_regular_list_NTM);
#line 165 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-regular-tail>", understand_regular_tail_NTM);
#line 169 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-regular-entry>", understand_regular_entry_NTM);
#line 176 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-list>", understand_property_list_NTM);
#line 181 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-tail>", understand_property_tail_NTM);
#line 185 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-entry>", understand_property_entry_NTM);
#line 251 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-sentence-object>", understand_sentence_object_NTM);
#line 255 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-sentence-object-uncond>", understand_sentence_object_uncond_NTM);
#line 260 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-sentence-object-tail>", understand_sentence_object_tail_NTM);
#line 264 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-sentence-entry>", understand_sentence_entry_NTM);
#line 293 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-as-this>", understand_as_this_NTM);
#line 304 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-ref>", understand_ref_NTM);
#line 376 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-command-sentence-object>", understand_command_sentence_object_NTM);
#line 405 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-sentence-object>", understand_property_sentence_object_NTM);
#line 409 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-sentence-object-unconditional>", understand_property_sentence_object_unconditional_NTM);
#line 414 "inform7/Chapter 25/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-reference>", understand_property_reference_NTM);
#line 97 "inform7/Chapter 25/Grammar Properties.w"
REGISTER_NONTERMINAL("<notable-parsing-variables>", notable_parsing_variables_NTM);
#line 187 "inform7/Chapter 25/Grammar Lines.w"
REGISTER_NONTERMINAL("<understand-condition>", understand_condition_NTM);
#line 212 "inform7/Chapter 25/Grammar Lines.w"
INTERNAL_NONTERMINAL("<spec-non-action-condition>", spec_non_action_condition_NTM, 1, 1000000000);
spec_non_action_condition_NTM->voracious = 0;
#line 62 "inform7/Chapter 25/Grammar Tokens.w"
REGISTER_NONTERMINAL("<grammar-token-breaking>", grammar_token_breaking_NTM);
#line 210 "inform7/Chapter 25/Grammar Tokens.w"
REGISTER_NONTERMINAL("<grammar-token>", grammar_token_NTM);
#line 228 "inform7/Chapter 25/Grammar Tokens.w"
REGISTER_NONTERMINAL("<standard-grammar-token>", standard_grammar_token_NTM);
#line 245 "inform7/Chapter 25/Grammar Tokens.w"
INTERNAL_NONTERMINAL("<named-grammar-token>", named_grammar_token_NTM, 1, 1000000000);
named_grammar_token_NTM->voracious = 0;
#line 78 "inform7/Chapter 25/Test Scripts.w"
REGISTER_NONTERMINAL("<test-sentence-subject>", test_sentence_subject_NTM);
#line 88 "inform7/Chapter 25/Test Scripts.w"
REGISTER_NONTERMINAL("<internal-test-case-name>", internal_test_case_name_NTM);
#line 112 "inform7/Chapter 25/Test Scripts.w"
REGISTER_NONTERMINAL("<test-sentence-object>", test_sentence_object_NTM);
#line 117 "inform7/Chapter 25/Test Scripts.w"
REGISTER_NONTERMINAL("<test-case-circumstance-list>", test_case_circumstance_list_NTM);
#line 122 "inform7/Chapter 25/Test Scripts.w"
REGISTER_NONTERMINAL("<test-case-circumstance>", test_case_circumstance_NTM);
#line 105 "inform7/Chapter 26/Figures.w"
REGISTER_NONTERMINAL("<figure-sentence-object>", figure_sentence_object_NTM);
#line 109 "inform7/Chapter 26/Figures.w"
REGISTER_NONTERMINAL("<figure-source>", figure_source_NTM);
#line 129 "inform7/Chapter 26/Figures.w"
REGISTER_NONTERMINAL("<notable-figures>", notable_figures_NTM);
#line 97 "inform7/Chapter 26/Sound Effects.w"
REGISTER_NONTERMINAL("<sound-sentence-object>", sound_sentence_object_NTM);
#line 101 "inform7/Chapter 26/Sound Effects.w"
REGISTER_NONTERMINAL("<sound-source>", sound_source_NTM);
#line 91 "inform7/Chapter 26/External Files.w"
REGISTER_NONTERMINAL("<external-file-sentence-subject>", external_file_sentence_subject_NTM);
#line 97 "inform7/Chapter 26/External Files.w"
REGISTER_NONTERMINAL("<external-file-name>", external_file_name_NTM);
#line 101 "inform7/Chapter 26/External Files.w"
REGISTER_NONTERMINAL("<external-file-owner>", external_file_owner_NTM);
#line 127 "inform7/Chapter 26/External Files.w"
REGISTER_NONTERMINAL("<external-file-sentence-object>", external_file_sentence_object_NTM);
#line 74 "inform7/Chapter 27/Plugins.w"
REGISTER_NONTERMINAL("<plugin-name>", plugin_name_NTM);
#line 99 "inform7/Chapter 27/Plugins.w"
REGISTER_NONTERMINAL("<language-element>", language_element_NTM);
#line 225 "inform7/Chapter 27/Plugins.w"
REGISTER_NONTERMINAL("<use-language-element-sentence-subject>", use_language_element_sentence_subject_NTM);
}