bl791's picture
download
raw
56.6 kB
/* ------------------------------------------------------------------------- */
/* "tables" : Maintains tables of dictionary, objects, actions, */
/* grammar and global variables; */
/* and constructs the tables part of the story file */
/* */
/* Part of Inform release 5 */
/* */
/* ------------------------------------------------------------------------- */
#include "header.h"
int no_attributes, no_properties, no_globals, no_fake_actions=0;
int dict_entries;
int release_number=1, statusline_flag=0;
int time_set=0;
char time_given[7];
int globals_size, properties_size;
int32 prop_defaults[64];
int prop_longflag[64];
int prop_additive[64];
char *properties_table;
int max_no_objects=0;
int resobj_flag = 0;
static int no_verbs=0, no_actions=0, no_adjectives=0,
no_objects=0, no_classes=0, classes_size=0;
static int fp_no_actions=0;
static int embedded_routine = 0;
static fpropt full_object;
/* ------------------------------------------------------------------------- */
/* Arrays used by this file */
/* ------------------------------------------------------------------------- */
#ifndef ALLOCATE_BIG_ARRAYS
static verbt vs[MAX_VERBS];
static objectt objects[MAX_OBJECTS];
static int table_init[MAX_STATIC_DATA];
static int32 actions[MAX_ACTIONS],
preactions[MAX_ACTIONS],
adjectives[MAX_ADJECTIVES];
static dict_word adjcomps[MAX_ADJECTIVES];
static int32 gvalues[240];
static int dict_places_list[MAX_DICT_ENTRIES],
dict_places_back[MAX_DICT_ENTRIES],
dict_places_inverse[MAX_DICT_ENTRIES];
static dict_word dict_sorts[MAX_DICT_ENTRIES];
static zip class_pointer[MAX_CLASS_TABLE_SIZE];
static int classes_here[MAX_CLASSES];
static int32 *classes_at[MAX_CLASSES];
#else
static verbt *vs;
static objectt *objects;
static int *table_init;
static int32 *actions,
*preactions,
*adjectives;
static dict_word *adjcomps;
static int32 *gvalues;
static int *dict_places_list,
*dict_places_back,
*dict_places_inverse;
static dict_word *dict_sorts;
static int *classes_here;
static int32 **classes_at;
static zip *class_pointer;
#endif
static char *verblist;
static char *verblist_p;
extern void tables_allocate_arrays(void)
{
#ifdef ALLOCATE_BIG_ARRAYS
vs = my_calloc(sizeof(verbt), MAX_VERBS, "verbs");
objects = my_calloc(sizeof(objectt), MAX_OBJECTS, "objects");
table_init = my_calloc(sizeof(int), MAX_STATIC_DATA, "static data");
actions = my_calloc(sizeof(int32), MAX_ACTIONS, "actions");
preactions = my_calloc(sizeof(int32), MAX_ACTIONS, "preactions");
adjectives = my_calloc(sizeof(int32), MAX_ADJECTIVES, "adjectives");
adjcomps = my_calloc(sizeof(dict_word), MAX_ADJECTIVES, "adj comps");
gvalues = my_calloc(sizeof(int32), 240, "global values");
dict_places_list = my_calloc(sizeof(int), MAX_DICT_ENTRIES,
"dictionary places list");
dict_places_back = my_calloc(sizeof(int), MAX_DICT_ENTRIES,
"dictionary places back");
dict_places_inverse = my_calloc(sizeof(int), MAX_DICT_ENTRIES,
"inverse of dictionary places");
dict_sorts = my_calloc(sizeof(dict_word), MAX_DICT_ENTRIES,
"dictionary sort codes");
class_pointer = my_malloc(MAX_CLASS_TABLE_SIZE, "class table");
classes_here = my_calloc(sizeof(int), MAX_CLASSES,
"inherited classes list");
classes_at = my_calloc(sizeof(int32), MAX_CLASSES,
"pointers to classes");
#endif
verblist = my_malloc(MAX_VERBSPACE, "register of verbs");
verblist_p = verblist;
}
extern void tables_free_arrays(void)
{
#ifdef ALLOCATE_BIG_ARRAYS
my_free(&vs, "verbs");
my_free(&objects, "objects");
my_free(&table_init, "static data");
my_free(&actions, "actions");
my_free(&preactions, "preactions");
my_free(&adjectives, "adjectives");
my_free(&adjcomps, "adj comps");
my_free(&gvalues, "global values");
my_free(&dict_places_list, "dictionary places list");
my_free(&dict_places_back, "dictionary places back");
my_free(&dict_places_inverse, "inverse of dictionary places");
my_free(&dict_sorts, "dictionary sort codes");
my_free(&class_pointer,"class table");
my_free(&classes_here, "inherited classes list");
my_free(&classes_at, "pointers to classes");
#endif
my_free(&verblist,"register of verbs");
}
/* ------------------------------------------------------------------------- */
/* A routine using an unusual ANSI library function: */
/* */
/* write_serialnumber writes today's date in the form YYMMDD as a string */
/* (as can be seen, the VAX doesn't know it) */
/* ------------------------------------------------------------------------- */
static void write_serialnumber(char *buffer)
{ time_t tt; tt=time(0);
if (time_set==0)
#ifdef TIME_UNAVAILABLE
sprintf(buffer,"940000");
#else
strftime(buffer,10,"%y%m%d",localtime(&tt));
#endif
else
sprintf(buffer,"%06s",time_given);
}
/* ------------------------------------------------------------------------- */
/* Dictionary table builder */
/* The dictionary is, so to speak, thumb-indexed: the beginning of each */
/* letter in the double-linked-list is marked. Experiments with */
/* increasing the number of markers (to the first two letters, say) result */
/* in extra bureaucracy which cancels out any speed gain. */
/* ------------------------------------------------------------------------- */
#define NUMBER_DICT_MARKERS 26
static int total_dict_entries;
static dict_word letter_keys[NUMBER_DICT_MARKERS];
static int letter_starts[NUMBER_DICT_MARKERS];
static int start_list;
static dict_word prepared_sort;
static int initial_letter;
static void dictionary_begin_pass(void)
{ int i, j;
dict_p=dictionary+7;
total_dict_entries=dict_entries; dict_entries=0;
if (pass_number==1)
{ start_list=0; dict_places_list[0]= -2; dict_places_back[0]= -1;
for (i=0; i<NUMBER_DICT_MARKERS; i++)
{ letter_keys[i].b[0]=0xff;
letter_starts[i]= -1;
}
}
else
{ for (j=start_list, i=0; i<total_dict_entries; i++)
{ dict_places_inverse[j]=i; j=dict_places_list[j]; }
}
}
static int compare_sorts(dict_word d1, dict_word d2)
{ int i;
for (i=0; i<6; i++) if (d1.b[i]!=d2.b[i]) return(d1.b[i]-d2.b[i]);
/* since memcmp(d1.b, d2.b, 6); doesn't work in the Unix port - ? */
return(0);
}
static dict_word dictionary_prepare(char *dword)
{ int i, j, k, wd[10]; int32 tot;
for (i=0, j=0; (i<9)&&(dword[j]!=0); i++, j++)
{ k=(int) dword[j];
if (k==(int) '\'')
obsolete_warning("use the ^ character for an apostrophe \
in a dictionary word, e.g. 'peter^s'");
if (k==(int) '^') k=(int) '\'';
k=chars_lookup[k];
if ((k>=26)&&(k<2*26)) k=k-26;
if ((k/26)!=0) wd[i++]=3+(k/26);
wd[i]=6+(k%26);
}
for (; i<9; i++) wd[i]=5;
InV3 { wd[6]=5; wd[7]=5; wd[8]=5;
if ((wd[5]==3)||(wd[5]==4)) wd[5]=5;
}
InV5 { if ((wd[8]==3)||(wd[8]==4)) wd[8]=5; }
initial_letter = wd[0]-6;
if (initial_letter<0)
{ error("Dictionary words must begin with a letter of the alphabet");
initial_letter=0;
}
/* Note... this doesn't depend on A to Z being contiguous in the
machine's character set */
tot = wd[2] + wd[1]*(1<<5) + wd[0]*(1<<10);
prepared_sort.b[1]=tot%0x100;
prepared_sort.b[0]=(tot/0x100)%0x100;
tot = wd[5] + wd[4]*(1<<5) + wd[3]*(1<<10);
prepared_sort.b[3]=tot%0x100;
prepared_sort.b[2]=(tot/0x100)%0x100;
tot = wd[8] + wd[7]*(1<<5) + wd[6]*(1<<10);
prepared_sort.b[5]=tot%0x100;
prepared_sort.b[4]=(tot/0x100)%0x100;
InV3 { prepared_sort.b[2]+=0x80; }
InV5 { prepared_sort.b[4]+=0x80; }
return(prepared_sort);
}
extern int dictionary_find(char *dword, int scope)
{ int32 j, j2, k, jlim;
dict_word i;
i=dictionary_prepare(dword);
if (scope==1) jlim=dict_entries; else jlim=total_dict_entries;
if (pass_number==1)
{ for (j=0; j<jlim; j++)
if (compare_sorts(i,dict_sorts[j])==0) return((int) j+1);
return(0);
}
if ((k=letter_starts[initial_letter])==-1) return(0);
j=initial_letter+1;
while ((j<NUMBER_DICT_MARKERS)&&((j2=letter_starts[j])==-1)) j++;
if (j==NUMBER_DICT_MARKERS) { j2= -2; }
while (k!=j2)
{
if ((compare_sorts(i,dict_sorts[k])==0)&&(k<jlim))
return(dict_places_inverse[k]+1);
k=dict_places_list[k];
}
return(0);
}
static void show_letter(int code)
{
if (code<6) { printf("."); return; }
printf("%c",(alphabet[0])[code-6]);
}
extern void show_dictionary(void)
{ int i, j; char *p;
int res=((version_number==3)?4:6);
printf("Dictionary contains %d entries:\n",dict_entries);
for (i=0; i<dict_entries; i++)
{ p=(char *)dictionary+7+(3+res)*i;
if (dict_entries==0)
printf("Entry %03d (%03d > %03d) at %04x: ",
i,dict_places_back[i],dict_places_list[i],
dictionary_offset+7+(3+res)*i);
else
printf("Entry %03d at %04x: ",i,dictionary_offset+7+(3+res)*i);
show_letter( (((int) p[0])&0x7c)/4 );
show_letter( 8*(((int) p[0])&0x3) + (((int) p[1])&0xe0)/32 );
show_letter( ((int) p[1])&0x1f );
show_letter( (((int) p[2])&0x7c)/4 );
show_letter( 8*(((int) p[2])&0x3) + (((int) p[3])&0xe0)/32 );
show_letter( ((int) p[3])&0x1f );
printf(" ");
for (j=0; j<3+res; j++) printf("%02x ",p[j]);
printf("\n");
}
}
static void dictionary_set_verb_number(char *dword, int to)
{ int i; zip *p;
int res=((version_number==3)?4:6);
i=dictionary_find(dword,1);
if (i!=0)
{ p=dictionary+7+(i-1)*(3+res)+res; p[1]=to;
}
}
extern int dictionary_add(char *dword, int x, int y, int z)
{ int off, i, k, l; zip *p; dict_word pcomp, qcomp;
int res=((version_number==3)?4:6);
if (dict_entries==MAX_DICT_ENTRIES)
{ memoryerror("MAX_DICT_ENTRIES",MAX_DICT_ENTRIES); }
i=dictionary_find(dword,1);
if (i!=0)
{ p=dictionary+7+(i-1)*(3+res)+res;
p[0]=(p[0])|x; p[1]=(p[1])|y; p[2]=(p[2])|z;
return(dictionary_offset+7+(3+res)*(i-1));
}
if (pass_number==1) i=dict_entries;
else { i=dict_places_inverse[dict_entries]; }
off=(3+res)*i+7;
p=dictionary+off;
p[0]=prepared_sort.b[0]; p[1]=prepared_sort.b[1];
p[2]=prepared_sort.b[2]; p[3]=prepared_sort.b[3];
InV5 { p[4]=prepared_sort.b[4]; p[5]=prepared_sort.b[5]; }
p[res]=x; p[res+1]=y; p[res+2]=z;
if (pass_number==1)
{ pcomp=prepared_sort;
if (dict_entries==0)
{ dict_places_list[0]= -2; dict_places_list[1]= -1;
goto PlaceFound;
}
l=initial_letter; do { k=letter_starts[l--]; } while ((l>=0)&&(k==-1));
if (k==-1) k=start_list;
for (; k!=-2; k=dict_places_list[k])
{ qcomp=dict_sorts[k];
if (compare_sorts(pcomp,qcomp)<0)
{ l=dict_places_back[k];
if (l==-1)
{ dict_places_list[dict_entries]=start_list;
dict_places_back[dict_entries]= -1;
dict_places_back[k]=dict_entries;
start_list=dict_entries; goto PlaceFound;
}
dict_places_list[l]=dict_entries;
dict_places_back[k]=dict_entries;
dict_places_list[dict_entries]=k;
dict_places_back[dict_entries]=l;
goto PlaceFound;
}
l=k;
}
dict_places_list[l]=dict_entries;
dict_places_back[dict_entries]=l;
dict_places_list[dict_entries]= -2;
PlaceFound: dict_sorts[dict_entries]=pcomp;
if (compare_sorts(pcomp,letter_keys[initial_letter])<0)
{ letter_keys[initial_letter]=pcomp;
letter_starts[initial_letter]=dict_entries;
}
}
dict_entries++; dict_p+=res+3;
/* show_dictionary(); */
return(dictionary_offset+off);
}
extern void list_object_tree(void)
{ int i;
printf("obj par nxt chl Object tree:\n");
for (i=0; i<no_objects; i++)
printf("%3d %3d %3d %3d\n",
i+1,objects[i].parent,objects[i].next, objects[i].child);
}
extern void list_verb_table(void)
{ int i, j, k;
for (i=0; i<no_verbs; i++)
{ printf("Verb entry %2d [%d]\n",i,vs[i].lines);
for (j=0; j<vs[i].lines; j++)
{ for (k=0; k<8; k++) printf("%03d ",vs[i].l[j].e[k]);
printf("\n");
}
}
}
/* ------------------------------------------------------------------------- */
/* Keep track of actions */
/* ------------------------------------------------------------------------- */
static int make_action(int32 addr)
{ int i;
if (no_actions>=MAX_ACTIONS)
memoryerror("MAX_ACTIONS",MAX_ACTIONS);
for (i=0; i<no_actions; i++) if (actions[i]==addr) return(i);
actions[no_actions]=addr; preactions[no_actions]= -1;
return(no_actions++);
}
extern int find_action(int32 addr)
{ int i;
for (i=0; i<fp_no_actions; i++) if (actions[i]==addr) return(i);
if (pass_number==2)
error("Action given in constant does not exist");
return(0);
}
extern void new_action(char *b, int c)
{ if ((printprops_mode==0)||(pass_number==2)) return;
printf("Action '%s' is numbered %d\n",b,c);
}
/* ------------------------------------------------------------------------- */
/* Parsing the grammar table, and making new adjectives and verbs */
/* (see the documentation for what the verb table it makes looks like) */
/* ------------------------------------------------------------------------- */
static int make_adjective(char *c)
{ int i; dict_word acomp;
acomp=dictionary_prepare(c);
for (i=0; i<no_adjectives; i++)
{ if (compare_sorts(acomp,adjcomps[i])==0) return(0xff-i);
}
adjectives[no_adjectives]=dictionary_add(c,8,0,0xff-no_adjectives);
adjcomps[no_adjectives]=acomp;
return(0xff-no_adjectives++);
}
static int find_verb(char *verb)
{ char *p;
p=verblist;
while (p<verblist_p)
{ if (strcmp(verb, p+2)==0) return(p[1]);
p=p+p[0];
}
return(-1);
}
static int verbspace_consumed = 0;
static void register_verb(char *verb, int number)
{ if (find_verb(verb)>=0)
{ error_named("Two different verb definitions refer to", verb);
return;
}
verbspace_consumed += strlen(verb)+3;
if (verbspace_consumed >= MAX_VERBSPACE)
memoryerror("MAX_VERBSPACE",MAX_VERBSPACE);
strcpy(verblist_p+2,verb);
verblist_p[1]=number;
verblist_p[0]=3+strlen(verb);
verblist_p += verblist_p[0];
}
static int32 parsing_routines[64];
static int no_prs;
static int debug_acts_writ[256];
static int action_exists[256];
static int grammar_line(int verbnum, int line, int i, char *b)
{ int j, l, flag=0; int32 k;
int vargs, vtokens, vinsert;
if (line>=MAX_LINES_PER_VERB)
{ error("Too many lines of grammar for verb: increase \
#define MAX_LINES_PER_VERB"); return(0); }
word(b,i++); flag=2;
if (b[0]==0) return(0);
if (strcmp(b,"*")!=0)
{ error_named("'*' divider expected, but found",b); return(0); }
vtokens=1; vargs=0; for (j=0; j<8; j++) vs[verbnum].l[line].e[j]=0;
do
{ word(b,i++);
if (b[0]==0) { error("'->' clause missing"); return(0); }
if (strcmp(b,"->")==0) break;
if (b[0]=='\"')
{ textword(b,i-1); vinsert=make_adjective(b);
}
else On_("noun") { vargs++; vinsert=0; }
else On_("held") { vargs++; vinsert=1; }
else On_("multi") { vargs++; vinsert=2; }
else On_("multiheld") { vargs++; vinsert=3; }
else On_("multiexcept") { vargs++; vinsert=4; }
else On_("multiinside") { vargs++; vinsert=5; }
else On_("creature") { vargs++; vinsert=6; }
else On_("special") { vargs++; vinsert=7; }
else On_("number") { vargs++; vinsert=8; }
else On_("scope")
{ word(b,i++);
if (strcmp(b,"=")!=0)
{ error_named("Expected '=' after 'scope' but found",b);
return(0);
}
word(b,i++);
j=find_symbol(b);
if ((j<0) || (stypes[j]!=1))
{ error_named(
"Expected routine after 'scope=' but found",b);
return(0);
}
for (l=0; (l<no_prs)
&& parsing_routines[l]!=svals[j]; l++) ;
parsing_routines[l]=svals[j]; if (l==no_prs) no_prs++;
vargs++; vinsert=l+80;
}
else On_("=")
{ if ((vtokens==0)||(vs[verbnum].l[line].e[vtokens-1]!=0))
{ error("'=' is only legal here as 'noun=Routine'");
return(0);
}
word(b,i++);
j=find_symbol(b);
if ((j<0) || (stypes[j]!=1))
{ error_named(
"Expected routine after 'noun=' but found", b);
return(0);
}
vtokens--;
for (l=0; (l<no_prs)
&& parsing_routines[l]!=svals[j]; l++) ;
parsing_routines[l]=svals[j]; if (l==no_prs) no_prs++;
vinsert=l+16;
}
else
{ j=find_symbol(b);
if ((j<0) || ((stypes[j]!=7)&&(stypes[j]!=1)))
{ error_named("No such token as",b); return(0); }
if (stypes[j]==7)
{ vargs++; vinsert=svals[j]+128;
}
else
{ vargs++;
for (l=0; (l<no_prs)
&& parsing_routines[l]!=svals[j]; l++) ;
parsing_routines[l]=svals[j]; if (l==no_prs) no_prs++;
vinsert=l+48;
}
}
vs[verbnum].l[line].e[vtokens]=vinsert;
vtokens++;
} while (1==1);
word(b,i++);
j=strlen(b)-3;
if ((j<0)||(b[j]!='S')||(b[j+1]!='u')||(b[j+2]!='b'))
sprintf(b+j+3,"Sub");
j=find_symbol(b);
if ((j==-1)&&(pass_number==2))
{ error_named("No such action routine as",b);
return(0);
}
if (j==-1) k=0;
else
{ if (stypes[j]!=1) { error_named("Not an action:",b); return(0); }
k=svals[j];
}
vs[verbnum].l[line].e[0]=vargs;
vs[verbnum].l[line].e[7]=make_action(k);
j=find_action(k);
if (action_exists[j]==0)
{ action_exists[j]=1; new_action(b,j);
}
if ((debugging_file==1)&&(k!=0)
&&(debug_acts_writ[j]==0))
{ debug_pass=2;
b[strlen(b)-3]=0;
write_debug_byte(8); write_debug_byte(j);
write_debug_string(b);
debug_pass=1;
if (pass_number==2) debug_acts_writ[j]=1;
}
return(i);
}
static int get_verb(char *b, int wn)
{ int j;
textword(b,wn); j=find_verb(b);
if (j==-1)
error_named("There is no previous grammar for the verb", b);
return(j);
}
extern void make_verb(char *b)
{ int i, i2, x=-1, flag=0;
int lines=0;
i=2;
word(b,i);
On_("meta") { i++; flag=2; }
i2=i;
do word(b,i2++); while (b[0]=='\"');
if (b[0]=='=') x=get_verb(b,i2++);
else
{ x=no_verbs;
if (no_verbs==MAX_VERBS)
memoryerror("MAX_VERBS",MAX_VERBS);
}
do
{ word(b,i);
if (b[0]!='\"') break;
textword(b,i++);
dictionary_add(b,0x41+flag,0xff-x,0);
if (pass_number==1) register_verb(b,x);
} while (1==1);
if (x!=no_verbs)
{ word(b,i2);
if (b[0]!=0)
error_named("Expected end of command but found",b);
return;
}
do
{ i=grammar_line(no_verbs, lines++,i,b);
} while (i!=0);
vs[no_verbs].lines=--lines;
no_verbs++;
}
extern void extend_verb(char *b)
{ int i, j, k, l, lines, mode;
word(b,2);
if (strcmp(b,"only")==0)
{ i=3; l=-1;
if (no_verbs==MAX_VERBS)
memoryerror("MAX_VERBS",MAX_VERBS);
do
{ j=get_verb(b,i++);
if (j==-1) return;
if ((l!=-1) && (j!=l) && (pass_number==1))
{ warning_named("Verb disagrees with previous verbs", b);
}
l=j;
dictionary_set_verb_number(b,0xff-no_verbs);
word(b,i);
} while (b[0]=='\"');
vs[no_verbs]=vs[j];
j=no_verbs++;
}
else { j=get_verb(b,2); if (j==-1) return; i=3; }
word(b,i); mode=3;
if (strcmp(b,"*")!=0)
{ mode=0;
if (strcmp(b,"replace")==0) mode=1;
if (strcmp(b,"first")==0) mode=2;
if (strcmp(b,"last")==0) mode=3;
if (mode==0)
{ error_named(
"Expected 'replace', 'last' or 'first' but found",b);
mode=3;
}
i++;
}
l=vs[j].lines; if (mode<=2) lines=0; else lines=l;
do
{ if (mode==2)
for (k=l; k>0; k--)
vs[j].l[k+lines]=vs[j].l[k-1+lines];
i=grammar_line(j, lines++,i,b);
} while (i!=0);
if (mode==2)
{ vs[j].lines = l+lines-1;
for (k=0; k<l; k++)
vs[j].l[k+lines-1]=vs[j].l[k+lines];
}
else vs[j].lines=--lines;
}
/* ------------------------------------------------------------------------- */
/* Object manufacture. Note that property lists are not kept for each */
/* object, only written in game-file format and then forgotten; but the */
/* object tree structure so far, is kept */
/* ------------------------------------------------------------------------- */
static int class_flag;
static int no_c_here;
static int properties(int w)
{ int i, k, x, y, pnw, flag=0; int32 j;
do
{ pnw=w;
word(sub_buffer,w++);
if (sub_buffer[0]==0) return(w-1);
/* if (strcmp(sub_buffer,",")==0) return(w-1); */
if (strcmp(sub_buffer,"has")==0) return(w-1);
if (strcmp(sub_buffer,"class")==0) return(w-1);
i=find_symbol(sub_buffer);
if (i==-1)
{ error_named("No such property as",sub_buffer);
return(w);
}
if (stypes[i]!=12)
{ error_named("Not a property:",sub_buffer);
return(w);
}
i=svals[i];
x=full_object.l++;
full_object.pp[x].num=i;
y=0;
do
{ word(sub_buffer,w++);
if (strcmp(sub_buffer,",")==0) break;
if (strcmp(sub_buffer,"has")==0) { w--; break; }
if (strcmp(sub_buffer,"class")==0) { w--; break; }
if (sub_buffer[0]==0) break;
if (strcmp(sub_buffer,"[")==0)
{ flag=1;
sprintf(sub_buffer,"Mb__%d",embedded_routine);
}
if ((i==1)&&(sub_buffer[0]=='\"'))
{ textword(sub_buffer,w-1);
j=dictionary_add(sub_buffer,0x80,0,0);
}
else
{ if ((pass_number==2)&&(y!=0))
{ k=find_symbol(sub_buffer);
if ((k!=-1)&&(stypes[k]==12))
{ warning_named(
"Missing ','? Property data seems to contain the property name",
sub_buffer);
}
}
j=constant_value(sub_buffer);
if (j==0)
{ if (prop_defaults[i]>=256) j=0x1000;
}
}
if ((j>=256)||(prop_longflag[i]==1))
full_object.pp[x].p[y++]=j/256;
full_object.pp[x].p[y++]=j%256;
} while (flag==0);
if (y==0) { full_object.pp[x].p[y++]=0;
full_object.pp[x].p[y++]=0;
}
full_object.pp[x].l=y;
InV3
{ if (y>8)
{ word(sub_buffer, pnw);
if (pass_number==2)
warning_named("Standard-game limit of 8 bytes per property exceeded \
(use Advanced to get 64), so truncating property", sub_buffer);
full_object.pp[x].l=8;
}
}
} while (flag==0);
sprintf(buffer,"[ Mb__%d",embedded_routine++);
do
{ word(sub_buffer,w++);
sprintf(buffer+strlen(buffer)," %s",sub_buffer);
} while (sub_buffer[0]!=0);
stack_line(buffer);
return(-1);
}
static int attributes(int w)
{ int i, negate_flag;
do
{ word(sub_buffer,w++);
if (sub_buffer[0]==0) return(w-1);
if ((strcmp(sub_buffer,"with")==0)
|| (strcmp(sub_buffer,",")==0)
|| (strcmp(sub_buffer,"class")==0)) return(w-1);
if (sub_buffer[0]=='~')
{ negate_flag=1; i=find_symbol(sub_buffer+1); }
else
{ negate_flag=0; i=find_symbol(sub_buffer); }
if ((i==-1)||(stypes[i]!=7))
{ error_named("No such attribute as",sub_buffer); return(w); }
i=svals[i];
if (negate_flag==0)
full_object.atts[i/8] =
full_object.atts[i/8] | (1 << (7-i%8));
else
full_object.atts[i/8] =
full_object.atts[i/8] & ~(1 << (7-i%8));
} while (1==1);
return(0);
}
static int classes(int w)
{ int i; zip *p;
do
{ word(sub_buffer,w++);
if (sub_buffer[0]==0) return(w-1);
if ((strcmp(sub_buffer,",")==0)
|| (strcmp(sub_buffer,"with")==0)
|| (strcmp(sub_buffer,"has")==0)) return(w-1);
i=find_symbol(sub_buffer);
if ((i==-1)||(stypes[i]!=13))
{ error_named("No such class as",sub_buffer); return(w); }
classes_here[no_c_here++]=svals[i];
/* printf("Inheriting attrs from %d\n",svals[i]); */
p=(zip *)classes_at[svals[i]-1];
for (i=0; i<6; i++) full_object.atts[i] |= p[i];
/* for (i=0; i<6; i++) printf("Data %d %x\n",i,p[i]); */
} while (1==1);
return(0);
}
static int write_properties(zip *p, char *shortname)
{ int i, l, j, k, count, number; zip *tmp; zip *from;
int32 props=0;
if (class_flag==0)
{ for (i=0;i<6;i++)
objects[no_objects].atts[i]=full_object.atts[i];
tmp=translate_text(p+1,shortname);
props=subtract_pointers(tmp,p);
p[0]=(props-1)/2;
}
else
{ p=class_pointer+classes_size;
classes_at[no_classes]=(int32 *) p;
/* printf("Class data at %08x\n",p); */
for (i=0;i<6;i++) p[i]=full_object.atts[i];
p+=6;
}
for (l=0; l<no_c_here; l++)
{ j=0; from=6+(zip *)classes_at[classes_here[l]-1];
/* printf("Inheriting from %d at %08x\n",classes_here[l],from); */
/* for (j=0; j<32; j++) printf("%02x ",from[j]); printf("\n"); j=0; */
while (from[j]!=0)
{ InV3
{ number=from[j]%32; count=1+from[j++]/32;
}
InV5
{ number=from[j]%64; count=1+from[j++]/64;
if (count>2) count=from[j++]%64;
}
/* printf("Inheriting no %d count %d\n",number,count); */
for (k=0; k<full_object.l; k++)
{ if (full_object.pp[k].num == number)
{ if ((number==1) || (prop_additive[number]!=0))
{ /* printf("Appending %d\n",number); */
for (i=full_object.pp[k].l;
i<full_object.pp[k].l+count; i++)
full_object.pp[k].p[i]=from[j++];
full_object.pp[k].l += count;
}
else
{ j+=count;
/* printf("Ignoring %d\n",number); */
}
goto DunInheriting;
}
}
k=full_object.l++;
full_object.pp[k].num = number;
full_object.pp[k].l = count;
for (i=0; i<count; i++)
full_object.pp[k].p[i]=from[j++];
/* printf("Creating %d\n",number); */
DunInheriting: ;
}
}
for (l=((version_number==3)?31:63); l>0; l--)
{ for (j=0; j<full_object.l; j++)
{ if (full_object.pp[j].num == l)
{ count=full_object.pp[j].l; number=full_object.pp[j].num;
InV3
{ p[props++] = number + (count - 1)*32;
}
InV5
{ switch(count)
{ case 1:
p[props++] = number; break;
case 2:
p[props++] = number + 0x40; break;
default:
p[props++] = number + 0x80;
p[props++] = count + 0x80;
break;
}
}
for (k=0; k<full_object.pp[j].l; k++)
{ p[props++]=full_object.pp[j].p[k];
}
}
}
}
p[props]=0; props++;
if (class_flag==1)
{
classes_size+=props+6;
if (classes_size >= MAX_CLASS_TABLE_SIZE)
memoryerror("MAX_CLASS_TABLE_SIZE",MAX_CLASS_TABLE_SIZE);
}
else
{
properties_size+=props;
if (properties_size >= MAX_PROP_TABLE_SIZE)
memoryerror("MAX_PROP_TABLE_SIZE",MAX_PROP_TABLE_SIZE);
}
return(props);
}
static char shortname_buffer[256];
extern void finish_object(void)
{ int j;
if (class_flag == 0)
{ j=objects[no_objects].propsize;
objects[no_objects].propsize=
write_properties((zip *) (properties_table+properties_size),
shortname_buffer);
if (pass_number==2)
{ if (j != objects[no_objects].propsize)
{ error("Object has altered in memory usage between passes: \
perhaps an attempt to use a routine name as value of a small property");
}
}
no_objects++;
if (pass_number==1) max_no_objects++;
}
else { write_properties(NULL,NULL); no_classes++; }
if (debugging_file==1)
{ write_present_linenum();
}
}
extern void resume_object(char *b, int j)
{ int flag=0, commas=0;
if (j==1)
{ word(b,1); flag=1;
if ((strcmp(b,"has")==0)
|| (strcmp(b,",")==0)
|| (strcmp(b,"class")==0)
|| (strcmp(b,"with")==0)) flag=0;
}
do
{ RO_Comma:
if (flag==0)
{ word(b,j++);
if (b[0]==0)
{ if (commas>0)
error("Object/class definition finishes with ','");
break;
}
}
if (strcmp(b,",")==0) { commas++; goto RO_Comma; }
if (commas>1)
error("Two commas ',' in a row in object/class definition");
commas=0;
if ((flag==1)||(strcmp(b,"with")==0))
{ j=properties(j);
if (j==-1) { resobj_flag=1; return; }
}
else if (strcmp(b,"has")==0) j=attributes(j);
else if (strcmp(b,"class")==0) j=classes(j);
else error_named("Expected 'with', 'has' or \
'class' in object/class definition but found",b);
flag=0;
} while (1==1);
finish_object();
}
extern void make_class(char *b)
{ class_flag = 1; no_c_here=0;
if (no_classes==MAX_CLASSES)
memoryerror("MAX_CLASSES", MAX_CLASSES);
word(b,2); new_symbol(b,no_classes+1,13);
if (debugging_file==1)
{ write_debug_byte(2); write_debug_linenum();
write_debug_string(b);
}
full_object.l=0;
full_object.atts[0]=0;
full_object.atts[1]=0;
full_object.atts[2]=0;
full_object.atts[3]=0;
full_object.atts[4]=0;
full_object.atts[5]=0;
resume_object(b,3);
}
static int near_obj;
extern void make_object(char *b, int nearby_flag)
{ int i, j, k, non=0, later, subof;
if (no_objects==MAX_OBJECTS)
memoryerror("MAX_OBJECTS", MAX_OBJECTS);
class_flag = 0; no_c_here=0;
word(b,2);
if (b[0]=='\"')
{ textword(b,2);
error_named(
"Expected an (internal) name for object, but found the string", b);
sprintf(b,"failedobj");
}
new_symbol(b,no_objects+1,9);
if (debugging_file==1)
{ write_debug_byte(3);
write_debug_byte((no_objects+1)/256);
write_debug_byte((no_objects+1)%256);
write_debug_linenum(); write_debug_string(b);
}
do
{ word(b,3+non);
if (b[0]!='\"')
{ new_symbol(b,no_objects+1,9); non++;
obsolete_warning("an object should only have one internal name");
}
} while (b[0]!='\"');
later=non+5;
if (nearby_flag==0)
{ word(b,4+non);
subof=0;
if ((b[0]==0)
|| (strcmp(b,",")==0)
|| (strcmp(b,"with")==0)
|| (strcmp(b,"has")==0)
|| (strcmp(b,"class")==0)) later--;
else
{ i=find_symbol(b);
if (i<0)
{ error_named("An object must be defined \
after the one which contains it: (so far) there is no such object as",b);
return;
}
if (stypes[i]!=9)
{ error_named("Not an object:",b); return; }
subof=svals[i];
}
near_obj=no_objects+1;
}
else
{ subof=near_obj; later--;
}
full_object.atts[0]=0;
full_object.atts[1]=0;
full_object.atts[2]=0;
full_object.atts[3]=0;
full_object.atts[4]=0;
full_object.atts[5]=0;
objects[no_objects].parent=subof;
objects[no_objects].next=0;
objects[no_objects].child=0;
full_object.l=0;
if (subof>0)
{ j=subof-1; k=objects[j].child;
if (k==0)
{ objects[j].child=no_objects+1; }
else
{ while(objects[k-1].next!=0) { k=objects[k-1].next; }
objects[k-1].next=no_objects+1;
}
}
textword(b,3+non);
if ((listobjects_mode==1) && ((pass_number==2)||(bothpasses_mode==1)))
printf("%3d \"%s\"\n",no_objects+1,b);
strcpy(shortname_buffer,b);
resume_object(b, later);
}
/* ------------------------------------------------------------------------- */
/* Making and initialising variables and arrays */
/* ------------------------------------------------------------------------- */
#define NON_VALUE (int32)0x100000L
extern void check_globals(void)
{ int i;
for (i=0;i<no_globals;i++)
if (gvalues[i]==NON_VALUE)
{ error("An initialised global variable was defined only in Pass 1");
return;
}
}
static int multiplier;
static int32 table_posn;
static int array_base;
int doing_table_mode;
static void finish_array(int32 i)
{ doing_table_mode=0;
if ((pass_number==1)&&(array_base!=globals_size))
{ if (multiplier==2)
{ table_init[array_base] = i/256;
table_init[array_base+1] = i%256;
}
else
{ if (i>=256)
error("A 'string' array can have at most 256 entries");
table_init[array_base] = i;
}
}
globals_size+=i*multiplier;
}
static void array_entry(int32 i, int32 j, char *b)
{ if (globals_size+i*multiplier >= MAX_STATIC_DATA)
memoryerror("MAX_STATIC_DATA", MAX_STATIC_DATA);
if (multiplier==1)
{ table_init[globals_size+i]=j;
if ((pass_number==2)&&(j>=256))
warning_named("Array entry too large for a byte:",b);
}
else
{ table_init[globals_size+2*i]=j/256;
table_init[globals_size+2*i+1]=j%256;
}
}
extern void assemble_table(char *b, int from)
{ int32 j; int i;
for (i=from;1==1;i++)
{ word(b,i); if (b[0]==0) return;
if (strcmp(b,"]")==0)
{ finish_array(table_posn);
return;
}
if (strcmp(b,"[")==0)
{ stack_line("]");
error("Expected ']' but found '['"); return;
}
j=constant_value(b);
array_entry(table_posn++, j, b);
}
return;
}
extern void make_global(char *b, int array_flag)
{ int32 i, j; int array_type, data_type, one_word;
word(b,2);
if (array_flag==0)
{ if (no_globals==235)
{ error("All 235 global variables already declared");
return;
}
if (pass_number==1)
{ new_symbol(b,no_globals,2);
if (debugging_file==1)
{ write_debug_byte(4); write_debug_byte(no_globals);
write_debug_string(b);
}
}
else
{ i=find_symbol(b);
no_globals=svals[i];
}
gvalues[no_globals]=0; no_globals++;
}
else
{ IfPass2
{ j=find_symbol(b);
svals[j]=variables_offset+globals_size;
}
else new_symbol(b,0x800+globals_size,8);
}
word(b,3);
if (b[0]==0)
{ if (array_flag==1) error("Missing array definition");
return;
}
if ((pass_number==1) && (array_flag==0))
gvalues[no_globals-1]=NON_VALUE;
if ((strcmp(b,"=")==0) && (array_flag==0))
{ word(b,4); i=constant_value(b);
if (pass_number==2) gvalues[no_globals-1]=i;
return;
}
if ((pass_number==2) && (array_flag==0))
gvalues[no_globals-1]=globals_size+variables_offset;
array_type=0; data_type=-1;
if ((array_flag==0)&&(strcmp(b,"data")==0)) { data_type=0; }
else if ((array_flag==0)&&(strcmp(b,"initial")==0)) { data_type=1; }
else if ((array_flag==0)&&(strcmp(b,"initstr")==0)) { data_type=2; }
else if (strcmp(b,"->")==0) array_type=0;
else if (strcmp(b,"-->")==0) array_type=1;
else if (strcmp(b,"string")==0) array_type=2;
else if (strcmp(b,"table")==0) array_type=3;
else { if (array_flag==0)
error_named("Expected '=', '->', '-->', 'string' or 'table' but found",b);
else
error_named("Expected '->', '-->', 'string' or 'table' but found",b);
return;
}
multiplier=1; if ((array_type==1) || (array_type==3)) multiplier=2;
word(b,5);
one_word=0; if (b[0]==0) one_word=1;
word(b,4);
if (b[0]==0) { error("Missing array definition"); return; }
switch(data_type)
{ case -1:
if (b[0]=='[') data_type=3;
else
{ if (one_word==1)
{ if (b[0]=='\"') data_type=2; else data_type=0;
}
else data_type=1;
}
break;
case 0: obsolete_warning("use '->' instead of 'data'"); break;
case 1: obsolete_warning("use '->' instead of 'initial'"); break;
case 2: obsolete_warning("use '->' instead of 'initstr'"); break;
}
array_base=globals_size;
if ((array_type==2) || (array_type==3)) globals_size+=multiplier;
switch(data_type)
{ case 0:
word(b,4); j=constant_value(b);
for (i=0; i<j; i++) array_entry(i, 0, b);
break;
case 1:
i=0;
do
{ word(b,4+i); if (b[0]==0) break;
if ((strcmp(b,"]")==0) || (strcmp(b,"[")==0))
{ error_named("Misplaced ",b); return; }
j=constant_value(b);
array_entry(i, j, b);
i++;
} while (1==1);
break;
case 2:
textword(b,4);
for (i=0; b[i]!=0; i++) array_entry(i, b[i], b);
break;
case 3:
doing_table_mode=1; table_posn=0;
if (one_word==0) assemble_table(b,5);
return;
}
finish_array(i);
}
/* ------------------------------------------------------------------------- */
/* Construct story file up as far as code area */
/* (see documentation for description of what goes on here) */
/* ------------------------------------------------------------------------- */
static void percentage(char *name, int32 x, int32 total)
{ printf(" %-20s %2d.%d%%\n",name,x*100/total,(x*1000/total)%10);
}
static int alloc_done_flag=0;
static char *version_name(int v)
{ switch(v)
{ case 3: return "Standard";
case 4: return "Plus";
case 5: return "Advanced";
case 6: return "graphical";
}
return "extended format";
}
extern void construct_storyfile(void)
{ char *p; unsigned char *u; int32 i, j, k; int32 excess;
int32 syns, objs, props, vars, parse, code, strs, dict, nparse,
actshere, preactshere;
int32 synsat, glpat, objat, propat, parsat;
int32 code_length, strings_length, alloc_size;
int32 limit;
int extend_offset;
if (alloc_done_flag==0)
{ alloc_done_flag=1;
alloc_size=0x4000 + subtract_pointers(dict_p,dictionary);
for (i=0; i<no_objects; i++) alloc_size+=objects[i].propsize;
output_p=my_malloc(alloc_size, "output buffer");
}
p=(char *)output_p; u=(unsigned char *) p;
for (i=0; i<=0x3f; i++) p[i]=0;
p[0]=actual_version; p[1]=statusline_flag*2;
p[2]=(release_number/256); p[3]=(release_number%256);
p[16]=0; p[17]=0;
write_serialnumber(buffer);
for (i=0; i<6; i++) p[18+i]=buffer[i];
syns=0x40;
u[syns]=0x80; p[syns+1]=0; syns+=2;
for (i=0; i+low_strings<low_strings_p; syns++, i++)
p[0x42+i]=low_strings[i];
p[24]=syns/256; p[25]=syns%256; synsat=syns;
for (i=0; i<3*32; i++)
{ p[syns++]=0; p[syns++]=0x20;
}
for (i=0; i<no_abbrevs; i++)
{ j=abbrev_values[i];
p[synsat+64+2*i]=j/256;
p[synsat+65+2*i]=j%256;
}
objs=syns;
p[10]=objs/256; p[11]=objs%256; glpat=objs;
p[objs]=0; p[objs+1]=0;
for (i=2; i< ((version_number==3)?32:64); i++)
{ p[objs+2*i-2]=prop_defaults[i]/256;
p[objs+2*i-1]=prop_defaults[i]%256;
}
objs+=2*i-2;
props=objs+((version_number==3)?9:14)*no_objects;
objat=objs; propat=props;
for (i=0; i<properties_size; i++)
p[props+i]=properties_table[i];
for (i=0; i<no_objects; i++)
{
InV3
{ p[objs]=objects[i].atts[0];
p[objs+1]=objects[i].atts[1];
p[objs+2]=objects[i].atts[2];
p[objs+3]=objects[i].atts[3];
p[objs+4]=objects[i].parent;
p[objs+5]=objects[i].next;
p[objs+6]=objects[i].child;
p[objs+7]=props/256;
p[objs+8]=props%256;
objs+=9;
}
InV5
{ p[objs]=objects[i].atts[0];
p[objs+1]=objects[i].atts[1];
p[objs+2]=objects[i].atts[2];
p[objs+3]=objects[i].atts[3];
p[objs+4]=objects[i].atts[4];
p[objs+5]=objects[i].atts[5];
p[objs+6]=(objects[i].parent)/256;
p[objs+7]=(objects[i].parent)%256;
p[objs+8]=(objects[i].next)/256;
p[objs+9]=(objects[i].next)%256;
p[objs+10]=(objects[i].child)/256;
p[objs+11]=(objects[i].child)%256;
p[objs+12]=props/256;
p[objs+13]=props%256;
objs+=14;
}
props+=objects[i].propsize;
}
vars=props;
p[12]=(vars/256); p[13]=(vars%256);
for (i=vars; i<vars+globals_size; i++) p[i]=table_init[i-vars];
for (i=0; i<240; i++)
{ j=gvalues[i];
p[vars+i*2] = j/256;
p[vars+i*2+1] = j%256;
}
parse=vars+globals_size;
p[14]=(parse/256); p[15]=(parse%256); parsat=parse;
nparse=parse+no_verbs*2;
for (i=0; i<no_verbs; i++)
{ p[parse]=(nparse/256); p[parse+1]=(nparse%256);
parse+=2;
p[nparse]=vs[i].lines; nparse++;
for (j=0; j<vs[i].lines; j++)
{ for (k=0; k<8; k++) p[nparse+k]=vs[i].l[j].e[k];
nparse+=8;
}
}
actshere=nparse; nparse+=2*no_actions;
preactshere=nparse; nparse+=2*no_actions;
p[nparse]=0; p[nparse+1]=no_adjectives; nparse+=2;
dict=nparse+4*no_adjectives;
adjectives_offset=nparse;
for (i=0; i<no_adjectives; i++)
{ j=adjectives[no_adjectives-i-1];
p[nparse]=j/256; p[nparse+1]=j%256; p[nparse+2]=0;
p[nparse+3]=(256-no_adjectives+i); nparse+=4;
}
dictionary[0]=3; dictionary[1]='.'; dictionary[2]=','; dictionary[3]='"';
dictionary[4]=(version_number==3)?7:9;
dictionary[5]=(dict_entries/256); dictionary[6]=(dict_entries%256);
p[8]=(dict/256); p[9]=(dict%256);
for (i=0; i+dictionary<dict_p; i++) p[dict+i]=dictionary[i];
code=dict+i;
while ((code%scale_factor) != 0) p[code++]=0;
p[4]=(code/256); p[5]=(code%256);
p[6]=((code+1)/256); p[7]=((code+1)%256);
Write_Code_At = code;
code_length=subtract_pointers(zcode_p,zcode);
strs=code+code_length;
while ((strs%scale_factor) != 0) strs++;
Write_Strings_At = strs;
strings_length=subtract_pointers(strings_p,strings);
Out_Size=strs+strings_length;
if (actual_version==3)
{ excess=Out_Size-((int32) 0x20000L); limit=128; }
if ((actual_version==4)||(actual_version==5))
{ excess=Out_Size-((int32) 0x40000L); limit=256; }
if ((actual_version==6)||(actual_version==8))
{ excess=Out_Size-((int32) 0x80000L); limit=512; }
if (actual_version==7) { excess=0; limit=320; }
if (excess>0)
{ sprintf(buffer,
"Story file exceeds version-%d limit (%dK) by %d bytes",
version_number, limit, excess);
fatalerror(buffer);
}
extend_offset=256;
if (no_objects+5 > extend_offset) extend_offset=no_objects+5;
if (extend_memory_map==1) code_offset = extend_offset*scale_factor;
else code_offset = code;
if (extend_memory_map==1)
strings_offset = code_offset + (strs-code);
else strings_offset = strs;
dictionary_offset = dict;
variables_offset = vars;
actions_offset = actshere;
preactions_offset = preactshere;
j=Out_Size/scale_factor;
p[26]=j/256; p[27]=j%256; p[28]=0; p[29]=0;
for (i=0; i<no_actions; i++)
{ j=(actions[i]+code_offset)/scale_factor;
p[actshere+i*2]=j/256; p[actshere+i*2+1]=j%256;
if (i<no_prs) j=(parsing_routines[i]+code_offset)/scale_factor;
else if (preactions[i]==-1) j=0;
else j=(preactions[i]+code_offset)/scale_factor;
p[preactshere+i*2]=j/256; p[preactshere+i*2+1]=j%256;
}
if (extend_memory_map==1)
{ j=Write_Code_At/scale_factor - extend_offset;
p[40]=j/256; p[41]=j%256;
j=Write_Code_At/scale_factor - extend_offset;
p[42]=j/256; p[43]=j%256;
}
/* From here on, it's all reportage: construction is finished */
if (statistics_mode==1)
{ int32 k_long, rate; char *k_str="";
k_long=(Out_Size/1024);
if ((Out_Size-1024*k_long) >= 512) { k_long++; k_str=""; }
else if ((Out_Size-1024*k_long) > 0) { k_str=".5"; }
rate=total_bytes_trans*1000/total_chars_trans;
if ((pass_number==2)||(bothpasses_mode==1))
{ printf("Input %d lines (%d statements, %d chars)",
total_source_line,internal_line,marker_in_file);
if (total_files_read > 1) { printf(" from %d files",
total_files_read); }
printf(
"\nVersion %d (%s) story file\n\
%4d objects (maximum %3d) %4d dictionary entries (maximum %d)\n\
%4d attributes (maximum %2d) %4d properties (maximum %2d)\n\
%4d adjectives (maximum 240) %4d verbs (maximum %d)\n\
%4d actions (maximum %3d) %4d abbreviations (maximum %d)\n",
actual_version, version_name(actual_version),
no_objects, ((version_number==3)?255:(MAX_OBJECTS-1)),
dict_entries, MAX_DICT_ENTRIES,
no_attributes, ((version_number==3)?32:48),
no_properties-2, ((version_number==3)?30:62),
no_adjectives,
no_verbs, MAX_VERBS,
no_actions, MAX_ACTIONS,
no_abbrevs, MAX_ABBREVS);
printf(
"%4d globals (maximum 240) %4d variable space (maximum %d)\n\
%4d symbols (maximum %4d) %4d routines (maximum %d)\n\
%4d classes (maximum %2d) %4d fake actions (unlimited)\n\
%4ld characters of text (compressed to %ld bytes, rate 0.%3ld)\n\
Output story file is %3ld%sK long (maximum %ldK)\n",
no_globals,
globals_size, MAX_STATIC_DATA,
no_symbols, MAX_SYMBOLS,
no_routines, MAX_ROUTINES,
no_classes, MAX_CLASSES,
no_fake_actions,
(long int) total_chars_trans,
(long int) total_bytes_trans,
(long int) rate,
(long int) k_long, k_str, (long int) limit);
}
}
if ((debugging_file==1)&&(pass_number==2))
{ debug_pass=2;
write_debug_byte(13);
write_debug_address(vars+480);
write_debug_address(parsat);
write_debug_address(dict);
write_debug_address(code);
write_debug_address(strs);
debug_pass=1;
}
if (offsets_mode==1)
{ if ((pass_number==2)||(bothpasses_mode==1))
{ printf(
"\nOffsets in story file:\n\
%05lx Synonyms %05lx Defaults %05lx Objects %05lx Properties\n\
%05lx Variables %05lx Parse table %05lx Actions %05lx Preactions\n\
%05lx Adjectives %05lx Dictionary %05lx Code %05lx Strings\n\n",
(long int) synsat, (long int) glpat, (long int) objat, (long int) propat,
(long int) vars, (long int) parsat, (long int) actshere,
(long int) preactshere, (long int) adjectives_offset, (long int) dict,
(long int) code, (long int) strs);
}
}
if (memory_map_mode==1)
{ if ((pass_number==2)||(bothpasses_mode==1))
{
printf("Dynamic +---------------------+ 00000\n");
printf("memory | header |\n");
printf(" +---------------------+ 00040\n");
printf(" | synonym strings |\n");
printf(" + - - - - - - - - - - + %05lx\n", (long int) synsat);
printf(" | synonym table |\n");
printf(" +---------------------+ %05lx\n", (long int) glpat);
printf(" | property defaults |\n");
printf(" + - - - - - - - - - - + %05lx\n", (long int) objat);
printf(" | objects |\n");
printf(" + - - - - - - - - - - + %05lx\n", (long int) propat);
printf(" | object short names |\n");
printf(" | and properties |\n");
printf(" +---------------------+ %05lx\n", (long int) vars);
printf(" | global variables |\n");
printf(" + - - - - - - - - - - + %05lx\n", ((long int) vars)+480L);
printf(" | arrays |\n");
printf(" +=====================+ %05lx\n", (long int) parsat);
printf("Static | grammar table |\n");
printf("cached + - - - - - - - - - - + %05lx\n", (long int) actshere);
printf("data | actions |\n");
printf(" + - - - - - - - - - - + %05lx\n", (long int) preactshere);
printf(" | preactions |\n");
printf(" + - - - - - - - - - - + %05lx\n",
(long int) adjectives_offset);
printf(" | adjectives |\n");
printf(" +---------------------+ %05lx\n", (long int) dict);
printf(" | dictionary |\n");
printf(" +---------------------+ %05lx\n", (long int) code);
printf("Static | Z-code |\n");
printf("paged +---------------------+ %05lx\n", (long int) strs);
printf("data | strings |\n");
printf(" +---------------------+ %05lx\n", (long int) Out_Size);
}
}
if (percentages_mode==1)
{ if ((pass_number==2)||(bothpasses_mode==1))
{ printf("Approximate percentage breakdown of story file:\n");
percentage("Z-code",code_length,Out_Size);
percentage("Static strings",strings_length,Out_Size);
percentage("Dictionary",code-dict,Out_Size);
percentage("Objects",vars-glpat,Out_Size);
percentage("Globals",parsat-vars,Out_Size);
percentage("Parsing tables",dict-parsat,Out_Size);
percentage("Header and synonyms",glpat,Out_Size);
percentage("Total of save area",parsat,Out_Size);
percentage("Total of text",total_bytes_trans,Out_Size);
}
}
if (frequencies_mode==1)
{ if ((pass_number==2)||(bothpasses_mode==1))
{ printf("How frequently abbreviations were used, and roughly\n");
printf("how many bytes they saved: ('_' denotes spaces)\n");
for (i=0; i<no_abbrevs; i++)
{ sprintf(sub_buffer,
(char *)abbreviations_at+i*MAX_ABBREV_LENGTH);
for (j=0; sub_buffer[j]!=0; j++)
if (sub_buffer[j]==' ') sub_buffer[j]='_';
printf("%10s %5d/%5d ",sub_buffer,abbrev_freqs[i],
2*((abbrev_freqs[i]-1)*abbrev_quality[i])/3);
if ((i%3)==2) printf("\n");
}
if ((i%3)!=0) printf("\n");
if (no_abbrevs==0) printf("None were declared.\n");
}
}
if (((statistics_mode==1)||(economy_mode==1))&&(pass_number==2))
{ printf("Essential size %ld bytes: %ld remaining\n",
(long int) Out_Size,
(long int) (((long int) (limit*1024L)) - ((long int) Out_Size)));
}
}
/* ------------------------------------------------------------------------- */
/* Begin pass */
/* ------------------------------------------------------------------------- */
extern void tables_begin_pass(void)
{ int i;
for (i=0; i<256; i++) debug_acts_writ[i]=0;
dictionary_begin_pass();
properties_size=0; classes_size=0;
no_objects=0; no_classes=0; embedded_routine=0;
no_verbs=0; fp_no_actions=no_actions; no_actions=0; no_adjectives=0;
no_properties=2; no_attributes=0; no_fake_actions=0;
no_globals=0; globals_size=0x1e0;
no_prs=0;
objects[0].parent=0; objects[0].child=0; objects[0].next=0;
doing_table_mode = 0;
}
extern void init_tables_vars(void)
{
no_fake_actions = 0;
release_number = 1;
statusline_flag = 0;
max_no_objects = 0;
resobj_flag = 0;
no_verbs = 0;
no_actions = 0;
no_adjectives = 0;
no_objects = 0;
no_classes = 0;
classes_size = 0;
fp_no_actions = 0;
embedded_routine = 0;
verbspace_consumed = 0;
alloc_done_flag = 0;
#ifdef ALLOCATE_BIG_ARRAYS
vs = NULL;
objects = NULL;
table_init = NULL;
actions = NULL;
preactions = NULL;
adjectives = NULL;
adjcomps = NULL;
gvalues = NULL;
dict_places_list = NULL;
dict_places_back = NULL;
dict_places_inverse = NULL;
dict_sorts = NULL;
class_pointer = NULL;
classes_here = NULL;
classes_at = NULL;
#endif
verblist = NULL;
output_p = NULL;
}

Xet Storage Details

Size:
56.6 kB
·
Xet hash:
b25fad21bdeccea143dfc91d0de6d0dc934d6a78be06d576779e0b031dd55a87

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.