Skip to content

Commit

Permalink
Fix and test case for Mantis bug 1977
Browse files Browse the repository at this point in the history
  • Loading branch information
ganelson committed Apr 10, 2022
1 parent d25ed3f commit fd2a34f
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 14 deletions.
12 changes: 12 additions & 0 deletions inform7/Tests/Test Problems/PM_CinderOverflow.txt
@@ -0,0 +1,12 @@
Foo is a room.
To zog:
let A0 be the player;
let A1 be the player;
let A2 be the player;
let A3 be the player;
let A4 be the player;
let A5 be the player;
let A6 be the player;
let A7 be the player;
let A8 be the player;
if every room encloses a thing that is A0 that is A1 that is A2 that is A3 that is A4 that is A5 that is A6 that is A7 that is A8, do nothing.
25 changes: 25 additions & 0 deletions inform7/Tests/Test Problems/_Results_Ideal/PM_CinderOverflow.txt
@@ -0,0 +1,25 @@
Inform 7 v10.1.0 has started.
I've now read your source text, which is 86 words long.
I've also read Basic Inform by Graham Nelson, which is 7691 words long.
I've also read English Language by Graham Nelson, which is 2328 words long.
I've also read Standard Rules by Graham Nelson, which is 32092 words long.
Problem__ PM_CinderOverflow
>--> You wrote 'if every room encloses a thing that is A0 that is A1 that is
A2 that is A3 that is A4 that is A5 that is A6 that is A7 that is A8' (source
text, line 12): but this complicated condition makes use of too many
temporary values, and will have to be simplified.
Problem__ PM_TooManyLocals
>--> You wrote 'if every room encloses a thing that is A0 that is A1 that is
A2 that is A3 that is A4 that is A5 that is A6 that is A7 that is A8' (source
text, line 12): but 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.
Inform 7 has finished.
9 changes: 5 additions & 4 deletions inform7/imperative-module/Chapter 3/Temporary Variables.w
Expand Up @@ -36,11 +36,12 @@ again for short periods of time:
int formal_par_vars_made = FALSE;
nonlocal_variable *formal_par_VAR[8];
nonlocal_variable *TemporaryVariables::formal_parameter(int i) {
if (i >= 8) internal_error("too many formal parameter variables");
if (formal_par_vars_made == FALSE) {
for (int i=0; i<8; i++) {
formal_par_VAR[i] = NonlocalVariables::new(EMPTY_WORDING, K_object, NULL);
RTVariables::set_hierarchy_location(formal_par_VAR[i],
TemporaryVariables::hl_of_formal_parameter(i));
for (int j=0; j<8; j++) {
formal_par_VAR[j] = NonlocalVariables::new(EMPTY_WORDING, K_object, NULL);
RTVariables::set_hierarchy_location(formal_par_VAR[j],
TemporaryVariables::hl_of_formal_parameter(j));
}
formal_par_vars_made = TRUE;
}
Expand Down
27 changes: 20 additions & 7 deletions inform7/imperative-module/Chapter 4/Cinders and Deferrals.w
Expand Up @@ -68,23 +68,34 @@ sets the kinds of the cinder values in the deferred function.
int Cinders::compile_cindered_values(pcalc_prop *prop, pcalc_prop_deferral *pdef) {
pcalc_prop_deferral *save_current_pdef = current_pdef;
current_pdef = pdef;
int N = 0;
int N = 0, overflowed = FALSE;
TRAVERSE_VARIABLE(atom);
TRAVERSE_PROPOSITION(atom, prop)
for (int i=0; i<atom->arity; i++)
N = Cinders::compile_cindered_value_in_term(&(atom->terms[i]), N);
N = Cinders::compile_cindered_value_in_term(&(atom->terms[i]), N, &overflowed);
current_pdef = save_current_pdef;
if (overflowed) {
current_sentence = pdef->deferred_from;
StandardProblems::sentence_problem(Task::syntax_tree(),
_p_(PM_CinderOverflow),
"this complicated condition makes use of too many temporary values",
"and will have to be simplified.");
}
return N;
}

int Cinders::compile_cindered_value_in_term(pcalc_term *pt, int N) {
int Cinders::compile_cindered_value_in_term(pcalc_term *pt, int N, int *overflowed) {
if (pt->function)
return Cinders::compile_cindered_value_in_term(&(pt->function->fn_of), N);
return Cinders::compile_cindered_value_in_term(&(pt->function->fn_of), N, overflowed);
if (pt->constant) {
if (Cinders::needs_to_be_cindered(pt->constant)) {
pt->cinder = N++;
CompileValues::to_code_val(pt->constant);
current_pdef->cinder_kinds[pt->cinder] = Specifications::to_kind(pt->constant);
if (N >= MAX_CINDERS_PER_DEFERRAL) {
*overflowed = TRUE;
} else {
pt->cinder = N++;
CompileValues::to_code_val(pt->constant);
current_pdef->cinder_kinds[pt->cinder] = Specifications::to_kind(pt->constant);
}
} else {
pt->cinder = -1;
}
Expand Down Expand Up @@ -146,6 +157,8 @@ kind *Cinders::kind_of_term(pcalc_term pt) {
if (pt.cinder >= 0) {
if (current_pdef == NULL)
internal_error("cindered term outside of deferral");
if (pt.cinder >= MAX_CINDERS_PER_DEFERRAL)
internal_error("cinder out of range");
return current_pdef->cinder_kinds[pt.cinder];
}
if (Specifications::is_phrasal(pt.constant))
Expand Down
Expand Up @@ -84,8 +84,8 @@ void DeferredPropositions::compile(pcalc_prop_deferral *pdef) {

@<Simplify the proposition by flipping negated quantifiers, if possible@>;

LOGIF(PREDICATE_CALCULUS, "Compiling deferred proposition: %d: reason %d: $D\n",
pdef->allocation_id, pdef->reason, proposition);
LOGIF(PREDICATE_CALCULUS, "Compiling %n as deferred proposition: %d: reason %d: $D\n",
pdef->ppd_iname, pdef->allocation_id, pdef->reason, proposition);

packaging_state save = Functions::begin(pdef->ppd_iname);

Expand Down
4 changes: 3 additions & 1 deletion inform7/imperative-module/Chapter 4/Deciding to Defer.w
Expand Up @@ -21,13 +21,15 @@ at runtime.

@d MULTIPURPOSE_DEFER 100 /* potentially any of the above */

@d MAX_CINDERS_PER_DEFERRAL 16

=
typedef struct pcalc_prop_deferral {
int reason; /* what we intend to do with it: one of the |*_DEFER| values above */
struct pcalc_prop *proposition_to_defer;
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) */
struct kind *cinder_kinds[MAX_CINDERS_PER_DEFERRAL]; /* the kinds of value being cindered (see below) */
struct inter_name *ppd_iname; /* function to implement this */
struct inter_name *rtp_iname; /* compile a string of the origin text for run-time problems? */
CLASS_DEFINITION
Expand Down

0 comments on commit fd2a34f

Please sign in to comment.