X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;ds=sidebyside;f=src%2Fobjects.c;h=88715bbf1fbb5cd4cdc37c966dac30dbb5d771db;hb=56a5292888e1d46fe3033cd1d5c636051692453f;hp=b957073d941f73c109ecf8b760bdb9d0d8dd0c54;hpb=d8d68d0bd4c45af6f0dc69b4fc33d37d961aca85;p=inform.git
diff --git a/src/objects.c b/src/objects.c
index b957073..88715bb 100644
--- a/src/objects.c
+++ b/src/objects.c
@@ -6,8 +6,8 @@
/* checks syntax and translates such directives into */
/* specifications for the object-maker. */
/* */
-/* Part of Inform 6.35 */
-/* copyright (c) Graham Nelson 1993 - 2021 */
+/* Part of Inform 6.42 */
+/* copyright (c) Graham Nelson 1993 - 2024 */
/* */
/* Inform is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
@@ -20,7 +20,7 @@
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
-/* along with Inform. If not, see https://gnu.org/licenses/ *
+/* along with Inform. If not, see https://gnu.org/licenses/ */
/* */
/* ------------------------------------------------------------------------- */
@@ -47,30 +47,36 @@ static fpropt full_object; /* "fpropt" is a typedef for a struct
sizeof(fpropt) is about 6200 bytes */
static fproptg full_object_g; /* Equivalent for Glulx. This object
is very small, since the large arrays
- are allocated dynamically by the
- Glulx compiler */
-static char shortname_buffer[766]; /* Text buffer to hold the short name
+ are allocated dynamically as
+ memory-lists */
+
+static char *shortname_buffer; /* Text buffer to hold the short name
(which is read in first, but
written almost last) */
+static memory_list shortname_buffer_memlist;
+
static int parent_of_this_obj;
-static char *classname_text, *objectname_text;
- /* For printing names of embedded
- routines only */
+static memory_list current_object_name; /* The name of the object currently
+ being defined. */
+
+static int current_classname_symbol; /* The symbol index of the class
+ currently being defined.
+ For error-checking and printing
+ names of embedded routines only. */
+
+static memory_list embedded_function_name; /* Temporary storage for inline
+ function name in property. */
/* ------------------------------------------------------------------------- */
/* Classes. */
/* ------------------------------------------------------------------------- */
/* Arrays defined below: */
/* */
-/* int32 class_begins_at[n] offset of properties block for */
-/* nth class (always an offset */
-/* inside the properties_table) */
+/* classinfo class_info[] Object number and prop offset */
/* int classes_to_inherit_from[] The list of classes to inherit */
/* from as taken from the current */
/* Nearby/Object/Class definition */
-/* int class_object_numbers[n] The number of the prototype-object */
-/* for the nth class */
/* ------------------------------------------------------------------------- */
int no_classes; /* Number of class defns made so far */
@@ -92,13 +98,19 @@ int no_attributes, /* Number of attributes defined so far */
others itself, so the variable begins
the compilation pass set to 4) */
+/* Print a PROPS trace line. The f flag is 0 for an attribute, 1 for
+ a common property, 2 for an individual property. */
static void trace_s(char *name, int32 number, int f)
-{ if (!printprops_switch) return;
- printf("%s %02ld ",(f==0)?"Attr":"Prop",(long int) number);
- if (f==0) printf(" ");
- else printf("%s%s",(prop_is_long[number])?"L":" ",
- (prop_is_additive[number])?"A":" ");
- printf(" %s\n",name);
+{ char *stype = "";
+ if (!printprops_switch) return;
+ if (f == 0) stype = "Attr";
+ else if (f == 1) stype = "Prop";
+ else if (f == 2) stype = "Indiv";
+ printf("%-5s %02ld ", stype, (long int) number);
+ if (f != 1) printf(" ");
+ else printf("%s%s",(commonprops[number].is_long)?"L":" ",
+ (commonprops[number].is_additive)?"A":" ");
+ printf(" %-24s (%s)\n", name, current_location_text());
}
extern void make_attribute(void)
@@ -122,9 +134,9 @@ game to get an extra 16)");
else {
if (no_attributes==NUM_ATTR_BYTES*8) {
discard_token_location(beginning_debug_location);
- error_numbered(
- "All attributes already declared -- increase NUM_ATTR_BYTES to use \
-more than",
+ error_fmt(
+ "All %d attributes already declared -- increase NUM_ATTR_BYTES to use \
+more",
NUM_ATTR_BYTES*8);
panic_mode_error_recovery();
put_token_back();
@@ -134,16 +146,17 @@ more than",
get_next_token();
i = token_value; name = token_text;
+ /* We hold onto token_text through the end of this Property directive, which should be okay. */
if (token_type != SYMBOL_TT)
{ discard_token_location(beginning_debug_location);
- ebf_error("new attribute name", token_text);
+ ebf_curtoken_error("new attribute name");
panic_mode_error_recovery();
put_token_back();
return;
}
- if (!(sflags[i] & UNKNOWN_SFLAG))
+ if (!(symbols[i].flags & UNKNOWN_SFLAG))
{ discard_token_location(beginning_debug_location);
- ebf_symbol_error("new attribute name", token_text, typename(stypes[i]), slines[i]);
+ ebf_symbol_error("new attribute name", token_text, typename(symbols[i].type), symbols[i].line);
panic_mode_error_recovery();
put_token_back();
return;
@@ -156,17 +169,16 @@ more than",
if ((token_type == DIR_KEYWORD_TT) && (token_value == ALIAS_DK))
{ get_next_token();
if (!((token_type == SYMBOL_TT)
- && (stypes[token_value] == ATTRIBUTE_T)))
+ && (symbols[token_value].type == ATTRIBUTE_T)))
{ discard_token_location(beginning_debug_location);
- ebf_error("an existing attribute name after 'alias'",
- token_text);
+ ebf_curtoken_error("an existing attribute name after 'alias'");
panic_mode_error_recovery();
put_token_back();
return;
}
- assign_symbol(i, svals[token_value], ATTRIBUTE_T);
- sflags[token_value] |= ALIASED_SFLAG;
- sflags[i] |= ALIASED_SFLAG;
+ assign_symbol(i, symbols[token_value].value, ATTRIBUTE_T);
+ symbols[token_value].flags |= ALIASED_SFLAG;
+ symbols[i].flags |= ALIASED_SFLAG;
}
else
{ assign_symbol(i, no_attributes++, ATTRIBUTE_T);
@@ -176,82 +188,133 @@ more than",
if (debugfile_switch)
{ debug_file_printf("");
debug_file_printf("%s", name);
- debug_file_printf("%d", svals[i]);
+ debug_file_printf("%d", symbols[i].value);
write_debug_locations(get_token_location_end(beginning_debug_location));
debug_file_printf("");
}
- trace_s(name, svals[i], 0);
+ trace_s(name, symbols[i].value, 0);
return;
}
+/* Format:
+ Property [long] [additive] name
+ Property [long] [additive] name alias oldname
+ Property [long] [additive] name defaultvalue
+ Property [long] individual name
+ */
extern void make_property(void)
{ int32 default_value, i;
- int additive_flag=FALSE; char *name;
- assembly_operand AO;
+ int keywords, prevkeywords;
+ char *name;
+ int namelen;
+ int additive_flag, indiv_flag;
debug_location_beginning beginning_debug_location =
get_token_location_beginning();
- if (!glulx_mode) {
- if (no_properties==((version_number==3)?32:64))
- { discard_token_location(beginning_debug_location);
- if (version_number==3)
- error("All 30 properties already declared (compile as \
-Advanced game to get an extra 62)");
- else
- error("All 62 properties already declared");
- panic_mode_error_recovery();
- put_token_back();
- return;
- }
- }
- else {
- if (no_properties==INDIV_PROP_START) {
- discard_token_location(beginning_debug_location);
- error_numbered("All properties already declared -- max is",
- INDIV_PROP_START);
- panic_mode_error_recovery();
- put_token_back();
- return;
- }
- }
-
+ /* The next bit is tricky. We want to accept any number of the keywords
+ "long", "additive", "individual" before the property name. But we
+ also want to accept "Property long" -- that's a legitimate
+ property name.
+ The solution is to keep track of which keywords we've seen in
+ a bitmask, and another for one token previous. That way we
+ can back up one token if there's no name visible. */
+ keywords = prevkeywords = 0;
do
{ directive_keywords.enabled = TRUE;
get_next_token();
- if ((token_type == DIR_KEYWORD_TT) && (token_value == LONG_DK))
- obsolete_warning("all properties are now automatically 'long'");
- else
- if ((token_type == DIR_KEYWORD_TT) && (token_value == ADDITIVE_DK))
- additive_flag = TRUE;
- else break;
+ if ((token_type == DIR_KEYWORD_TT) && (token_value == LONG_DK)) {
+ prevkeywords = keywords;
+ keywords |= 1;
+ }
+ else if ((token_type == DIR_KEYWORD_TT) && (token_value == ADDITIVE_DK)) {
+ prevkeywords = keywords;
+ keywords |= 2;
+ }
+ else if ((token_type == DIR_KEYWORD_TT) && (token_value == INDIVIDUAL_DK)) {
+ prevkeywords = keywords;
+ keywords |= 4;
+ }
+ else {
+ break;
+ }
} while (TRUE);
-
+
+ /* Re-parse the name with keywords turned off. (This allows us to
+ accept a property name like "table".) */
put_token_back();
directive_keywords.enabled = FALSE;
get_next_token();
+ if (token_type != SYMBOL_TT && keywords) {
+ /* This can't be a name. Try putting back the last keyword. */
+ keywords = prevkeywords;
+ put_token_back();
+ put_token_back();
+ get_next_token();
+ }
+
+ additive_flag = indiv_flag = FALSE;
+ if (keywords & 1)
+ obsolete_warning("all properties are now automatically 'long'");
+ if (keywords & 2)
+ additive_flag = TRUE;
+ if (keywords & 4)
+ indiv_flag = TRUE;
+
i = token_value; name = token_text;
+ /* We hold onto token_text through the end of this Property directive, which should be okay. */
if (token_type != SYMBOL_TT)
{ discard_token_location(beginning_debug_location);
- ebf_error("new property name", token_text);
+ ebf_curtoken_error("new property name");
panic_mode_error_recovery();
put_token_back();
return;
}
- if (!(sflags[i] & UNKNOWN_SFLAG))
+ if (!(symbols[i].flags & UNKNOWN_SFLAG))
{ discard_token_location(beginning_debug_location);
- ebf_symbol_error("new property name", token_text, typename(stypes[i]), slines[i]);
+ ebf_symbol_error("new property name", token_text, typename(symbols[i].type), symbols[i].line);
panic_mode_error_recovery();
put_token_back();
return;
}
+ if (indiv_flag) {
+ int this_identifier_number;
+
+ if (additive_flag)
+ { error("'individual' incompatible with 'additive'");
+ panic_mode_error_recovery();
+ put_token_back();
+ return;
+ }
+
+ this_identifier_number = no_individual_properties++;
+ assign_symbol(i, this_identifier_number, INDIVIDUAL_PROPERTY_T);
+ if (debugfile_switch) {
+ debug_file_printf("");
+ debug_file_printf
+ ("%s", name);
+ debug_file_printf
+ ("%d", this_identifier_number);
+ debug_file_printf("");
+ }
+ trace_s(name, symbols[i].value, 2);
+ return;
+ }
+
directive_keywords.enabled = TRUE;
get_next_token();
directive_keywords.enabled = FALSE;
- if (strcmp(name+strlen(name)-3, "_to") == 0) sflags[i] |= STAR_SFLAG;
+ namelen = strlen(name);
+ if (namelen > 3 && strcmp(name+namelen-3, "_to") == 0) {
+ /* Direction common properties "n_to", etc are compared in some
+ libraries. They have STAR_SFLAG to tell us to skip a warning. */
+ symbols[i].flags |= STAR_SFLAG;
+ }
+
+ /* Now we might have "alias" or a default value (but not both). */
if ((token_type == DIR_KEYWORD_TT) && (token_value == ALIAS_DK))
{ discard_token_location(beginning_debug_location);
@@ -263,67 +326,93 @@ Advanced game to get an extra 62)");
}
get_next_token();
if (!((token_type == SYMBOL_TT)
- && (stypes[token_value] == PROPERTY_T)))
- { ebf_error("an existing property name after 'alias'",
- token_text);
+ && (symbols[token_value].type == PROPERTY_T)))
+ { ebf_curtoken_error("an existing property name after 'alias'");
panic_mode_error_recovery();
put_token_back();
return;
}
- assign_symbol(i, svals[token_value], PROPERTY_T);
- trace_s(name, svals[i], 1);
- sflags[token_value] |= ALIASED_SFLAG;
- sflags[i] |= ALIASED_SFLAG;
+ assign_symbol(i, symbols[token_value].value, PROPERTY_T);
+ trace_s(name, symbols[i].value, 1);
+ symbols[token_value].flags |= ALIASED_SFLAG;
+ symbols[i].flags |= ALIASED_SFLAG;
return;
}
+ /* We now know we're allocating a new common property. Make sure
+ there's room. */
+ if (!glulx_mode) {
+ if (no_properties==((version_number==3)?32:64))
+ { discard_token_location(beginning_debug_location);
+ /* The maximum listed here includes "name" but not the
+ unused zero value or the two hidden properties (class
+ inheritance and indiv table). */
+ if (version_number==3)
+ error("All 29 properties already declared (compile as \
+Advanced game to get 32 more)");
+ else
+ error("All 61 properties already declared");
+ panic_mode_error_recovery();
+ put_token_back();
+ return;
+ }
+ }
+ else {
+ if (no_properties==INDIV_PROP_START) {
+ discard_token_location(beginning_debug_location);
+ error_fmt(
+ "All %d properties already declared (increase INDIV_PROP_START to get more)",
+ INDIV_PROP_START-3);
+ panic_mode_error_recovery();
+ put_token_back();
+ return;
+ }
+ }
+
default_value = 0;
put_token_back();
if (!((token_type == SEP_TT) && (token_value == SEMICOLON_SEP)))
- { AO = parse_expression(CONSTANT_CONTEXT);
+ {
+ assembly_operand AO = parse_expression(CONSTANT_CONTEXT);
default_value = AO.value;
if (AO.marker != 0)
backpatch_zmachine(AO.marker, PROP_DEFAULTS_ZA,
(no_properties-1) * WORDSIZE);
}
- prop_default_value[no_properties] = default_value;
- prop_is_long[no_properties] = TRUE;
- prop_is_additive[no_properties] = additive_flag;
+ commonprops[no_properties].default_value = default_value;
+ commonprops[no_properties].is_long = TRUE;
+ commonprops[no_properties].is_additive = additive_flag;
assign_symbol(i, no_properties++, PROPERTY_T);
if (debugfile_switch)
{ debug_file_printf("");
debug_file_printf("%s", name);
- debug_file_printf("%d", svals[i]);
+ debug_file_printf("%d", symbols[i].value);
write_debug_locations
(get_token_location_end(beginning_debug_location));
debug_file_printf("");
}
- trace_s(name, svals[i], 1);
+ trace_s(name, symbols[i].value, 1);
}
/* ------------------------------------------------------------------------- */
/* Properties. */
/* ------------------------------------------------------------------------- */
-int32 *prop_default_value; /* Default values for properties */
-int *prop_is_long, /* Property modifiers, TRUE or FALSE:
- "long" means "never write a 1-byte
- value to this property", and is an
- obsolete feature: since Inform 5
- all properties have been "long" */
- *prop_is_additive; /* "additive" means that values
- accumulate rather than erase each
- other during class inheritance */
-char *properties_table; /* Holds the table of property values
+commonpropinfo *commonprops; /* Info about common properties
+ (fixed allocation of
+ INDIV_PROP_START entries) */
+
+uchar *properties_table; /* Holds the table of property values
(holding one block for each object
and coming immediately after the
object tree in Z-memory) */
+memory_list properties_table_memlist;
int properties_table_size; /* Number of bytes in this table */
/* ------------------------------------------------------------------------- */
@@ -363,6 +452,7 @@ static int individual_prop_table_size; /* Size of the table of individual
properties so far for current obj */
uchar *individuals_table; /* Table of records, each being the
i.p. table for an object */
+ memory_list individuals_table_memlist;
int i_m; /* Write mark position in the above */
int individuals_length; /* Extent of individuals_table */
@@ -370,13 +460,16 @@ static int individual_prop_table_size; /* Size of the table of individual
/* Arrays used by this file */
/* ------------------------------------------------------------------------- */
-objecttz *objectsz; /* Z-code only */
-objecttg *objectsg; /* Glulx only */
-uchar *objectatts; /* Glulx only */
-static int *classes_to_inherit_from;
-int *class_object_numbers;
-int32 *class_begins_at;
-
+objecttz *objectsz; /* Allocated to no_objects; Z-code only */
+memory_list objectsz_memlist;
+objecttg *objectsg; /* Allocated to no_objects; Glulx only */
+static memory_list objectsg_memlist;
+uchar *objectatts; /* Allocated to no_objects; Glulx only */
+static memory_list objectatts_memlist;
+static int *classes_to_inherit_from; /* Allocated to no_classes_to_inherit_from */
+static memory_list classes_to_inherit_from_memlist;
+classinfo *class_info; /* Allocated up to no_classes */
+memory_list class_info_memlist;
/* ------------------------------------------------------------------------- */
/* Tracing for compiler maintenance */
@@ -384,10 +477,24 @@ int32 *class_begins_at;
extern void list_object_tree(void)
{ int i;
- printf("obj par nxt chl Object tree:\n");
- for (i=0; i 0) ? symbols[sym].name : "...");
+ printf("%3d %-32s %3d %3d %3d\n",
+ i+1, symname,
+ objectsz[i].parent, objectsz[i].next, objectsz[i].child);
+ }
+ else {
+ int sym = objectsg[i].symbol;
+ char *symname = ((sym > 0) ? symbols[sym].name : "...");
+ printf("%3d %-32s %3d %3d %3d\n",
+ i+1, symname,
+ objectsg[i].parent, objectsg[i].next, objectsg[i].child);
+ }
+ }
}
/* ------------------------------------------------------------------------- */
@@ -437,8 +544,8 @@ static void property_inheritance_z(void)
for (class=0; class 64)
+ fatalerror("More than 64 property entries in an object");
for (k=0; k= 32)
+ {
+ if (i >= 32)
{ error("An additive property has inherited \
so many values that the list has overflowed the maximum 32 entries");
break;
}
- full_object.pp[k].ao[i].value = mark + j;
+ if ((version_number==3) && i >= 4)
+ { error("An additive property has inherited \
+so many values that the list has overflowed the maximum 4 entries");
+ break;
+ }
+ INITAOTV(&full_object.pp[k].ao[i], LONG_CONSTANT_OT, mark + j);
j += 2;
full_object.pp[k].ao[i].marker = INHERIT_MV;
- full_object.pp[k].ao[i].type = LONG_CONSTANT_OT;
}
full_object.pp[k].l += prop_length/2;
}
@@ -499,7 +613,6 @@ so many values that the list has overflowed the maximum 32 entries");
if (prop_number==3)
{ int y, z, class_block_offset;
- uchar *p;
/* Property 3 holds the address of the table of
instance variables, so this is the case where
@@ -510,35 +623,29 @@ so many values that the list has overflowed the maximum 32 entries");
class_block_offset = class_prop_block[j-2]*256
+ class_prop_block[j-1];
- p = individuals_table + class_block_offset;
z = class_block_offset;
- while ((p[0]!=0)||(p[1]!=0))
+ while ((individuals_table[z]!=0)||(individuals_table[z+1]!=0))
{ int already_present = FALSE, l;
for (l = full_object.pp[k].ao[0].value; l < i_m;
l = l + 3 + individuals_table[l + 2])
- if (individuals_table[l] == p[0]
- && individuals_table[l + 1] == p[1])
+ if (individuals_table[l] == individuals_table[z]
+ && individuals_table[l + 1] == individuals_table[z+1])
{ already_present = TRUE; break;
}
if (already_present == FALSE)
- { if (module_switch)
- backpatch_zmachine(IDENT_MV,
- INDIVIDUAL_PROP_ZA, i_m);
- if (i_m+3+p[2] > MAX_INDIV_PROP_TABLE_SIZE)
- memoryerror("MAX_INDIV_PROP_TABLE_SIZE",
- MAX_INDIV_PROP_TABLE_SIZE);
- individuals_table[i_m++] = p[0];
- individuals_table[i_m++] = p[1];
- individuals_table[i_m++] = p[2];
- for (y=0;y < p[2]/2;y++)
+ {
+ ensure_memory_list_available(&individuals_table_memlist, i_m+3+individuals_table[z+2]);
+ individuals_table[i_m++] = individuals_table[z];
+ individuals_table[i_m++] = individuals_table[z+1];
+ individuals_table[i_m++] = individuals_table[z+2];
+ for (y=0;y < individuals_table[z+2]/2;y++)
{ individuals_table[i_m++] = (z+3+y*2)/256;
individuals_table[i_m++] = (z+3+y*2)%256;
backpatch_zmachine(INHERIT_INDIV_MV,
INDIVIDUAL_PROP_ZA, i_m-2);
}
}
- z += p[2] + 3;
- p += p[2] + 3;
+ z += individuals_table[z+2] + 3;
}
individuals_length = i_m;
}
@@ -556,18 +663,19 @@ so many values that the list has overflowed the maximum 32 entries");
a new property added to full_object */
k=full_object.l++;
+ if (k >= 64)
+ fatalerror("More than 64 property entries in an object");
full_object.pp[k].num = prop_number;
full_object.pp[k].l = prop_length/2;
for (i=0; i MAX_INDIV_PROP_TABLE_SIZE)
- memoryerror("MAX_INDIV_PROP_TABLE_SIZE",
- MAX_INDIV_PROP_TABLE_SIZE);
- individuals_table[i_m++] = p[0];
- individuals_table[i_m++] = p[1];
- individuals_table[i_m++] = p[2];
- for (y=0;y < p[2]/2;y++)
+ while ((individuals_table[z]!=0)||(individuals_table[z+1]!=0))
+ {
+ ensure_memory_list_available(&individuals_table_memlist, i_m+3+individuals_table[z+2]);
+ individuals_table[i_m++] = individuals_table[z];
+ individuals_table[i_m++] = individuals_table[z+1];
+ individuals_table[i_m++] = individuals_table[z+2];
+ for (y=0;y < individuals_table[z+2]/2;y++)
{ individuals_table[i_m++] = (z+3+y*2)/256;
individuals_table[i_m++] = (z+3+y*2)%256;
backpatch_zmachine(INHERIT_INDIV_MV,
INDIVIDUAL_PROP_ZA, i_m-2);
}
- z += p[2] + 3;
- p += p[2] + 3;
+ z += individuals_table[z+2] + 3;
}
individuals_length = i_m;
}
@@ -614,9 +715,7 @@ so many values that the list has overflowed the maximum 32 entries");
if (individual_prop_table_size > 0)
{
- if (i_m+2 > MAX_INDIV_PROP_TABLE_SIZE)
- memoryerror("MAX_INDIV_PROP_TABLE_SIZE",
- MAX_INDIV_PROP_TABLE_SIZE);
+ ensure_memory_list_available(&individuals_table_memlist, i_m+2);
individuals_table[i_m++] = 0;
individuals_table[i_m++] = 0;
@@ -641,8 +740,8 @@ static void property_inheritance_g(void)
ASSERT_GLULX();
for (class=0; class MAX_OBJ_PROP_TABLE_SIZE) {
- memoryerror("MAX_OBJ_PROP_TABLE_SIZE",MAX_OBJ_PROP_TABLE_SIZE);
- }
-
+
+ ensure_memory_list_available(&full_object_g.propdata_memlist, full_object_g.propdatasize + prop_length);
for (i=0; i MAX_OBJ_PROP_TABLE_SIZE) {
- memoryerror("MAX_OBJ_PROP_TABLE_SIZE",MAX_OBJ_PROP_TABLE_SIZE);
- }
+ ensure_memory_list_available(&full_object_g.propdata_memlist, full_object_g.propdatasize + prop_length);
for (i=0; i=from; prop_number--)
{ for (j=0; j= MAX_PROP_TABLE_SIZE)
- memoryerror("MAX_PROP_TABLE_SIZE",MAX_PROP_TABLE_SIZE);
+ {
+ int prop_length = 2*full_object.pp[j].l;
+ ensure_memory_list_available(&properties_table_memlist, mark+2+prop_length);
if (version_number == 3)
- p[mark++] = prop_number + (prop_length - 1)*32;
+ properties_table[mark++] = prop_number + (prop_length - 1)*32;
else
{ switch(prop_length)
{ case 1:
- p[mark++] = prop_number; break;
+ properties_table[mark++] = prop_number; break;
case 2:
- p[mark++] = prop_number + 0x40; break;
+ properties_table[mark++] = prop_number + 0x40; break;
default:
- p[mark++] = prop_number + 0x80;
- p[mark++] = prop_length + 0x80; break;
+ properties_table[mark++] = prop_number + 0x80;
+ properties_table[mark++] = prop_length + 0x80; break;
}
}
for (k=0; k= 32) {
+ /* We catch this earlier, but we'll check again to avoid overflowing ao[] */
+ error("Too many values for Z-machine property");
+ break;
+ }
+ if (full_object.pp[j].ao[k].marker != 0)
backpatch_zmachine(full_object.pp[j].ao[k].marker,
PROP_ZA, mark);
- p[mark++] = full_object.pp[j].ao[k].value/256;
- p[mark++] = full_object.pp[j].ao[k].value%256;
+ properties_table[mark++] = full_object.pp[j].ao[k].value/256;
+ properties_table[mark++] = full_object.pp[j].ao[k].value%256;
}
}
}
}
- p[mark++]=0;
+ ensure_memory_list_available(&properties_table_memlist, mark+1);
+ properties_table[mark++]=0;
return(mark);
}
@@ -801,28 +898,32 @@ static int write_property_block_z(char *shortname)
Return the number of bytes written to the block. */
int32 mark = properties_table_size, i;
- uchar *p = (uchar *) properties_table;
/* printf("Object at %04x\n", mark); */
if (shortname != NULL)
- { uchar *tmp;
- if (mark+1+510 >= MAX_PROP_TABLE_SIZE)
- memoryerror("MAX_PROP_TABLE_SIZE",MAX_PROP_TABLE_SIZE);
- tmp = translate_text(p+mark+1,p+mark+1+510,shortname,STRCTX_OBJNAME);
- if (!tmp) error ("Short name of object exceeded 765 Z-characters");
- i = subtract_pointers(tmp,(p+mark+1));
- p[mark] = i/2;
+ {
+ /* The limit of 510 bytes, or 765 Z-characters, is a Z-spec limit. */
+ i = translate_text(510,shortname,STRCTX_OBJNAME);
+ if (i < 0) {
+ error ("Short name of object exceeded 765 Z-characters");
+ i = 0;
+ }
+ ensure_memory_list_available(&properties_table_memlist, mark+1+i);
+ memcpy(properties_table + mark+1, translated_text, i);
+ properties_table[mark] = i/2;
mark += i+1;
}
if (current_defn_is_class)
- { mark = write_properties_between(p,mark,3,3);
+ { mark = write_properties_between(mark,3,3);
+ ensure_memory_list_available(&properties_table_memlist, mark+6);
for (i=0;i<6;i++)
- p[mark++] = full_object.atts[i];
- class_begins_at[no_classes++] = mark;
+ properties_table[mark++] = full_object.atts[i];
+ ensure_memory_list_available(&class_info_memlist, no_classes+1);
+ class_info[no_classes++].begins_at = mark;
}
- mark = write_properties_between(p, mark, 1, (version_number==3)?31:63);
+ mark = write_properties_between(mark, 1, (version_number==3)?31:63);
i = mark - properties_table_size;
properties_table_size = mark;
@@ -859,12 +960,13 @@ static int32 write_property_block_g(void)
int ix, jx, kx, totalprops;
int32 mark = properties_table_size;
int32 datamark;
- uchar *p = (uchar *) properties_table;
if (current_defn_is_class) {
+ ensure_memory_list_available(&properties_table_memlist, mark+NUM_ATTR_BYTES);
for (i=0;i= MAX_PROP_TABLE_SIZE)
- memoryerror("MAX_PROP_TABLE_SIZE",MAX_PROP_TABLE_SIZE);
- WriteInt32(p+mark, totalprops);
+ ensure_memory_list_available(&properties_table_memlist, mark+4);
+ WriteInt32(properties_table+mark, totalprops);
mark += 4;
datamark = mark + 10*totalprops;
@@ -903,11 +1004,10 @@ static int32 write_property_block_g(void)
jx= MAX_PROP_TABLE_SIZE)
- memoryerror("MAX_PROP_TABLE_SIZE",MAX_PROP_TABLE_SIZE);
+ ensure_memory_list_available(&properties_table_memlist, datamark+4*full_object_g.props[jx].datalen);
for (kx=0; kx= MAX_PROP_TABLE_SIZE)
- memoryerror("MAX_PROP_TABLE_SIZE",MAX_PROP_TABLE_SIZE);
- WriteInt16(p+mark, propnum);
+ ensure_memory_list_available(&properties_table_memlist, mark+10);
+ WriteInt16(properties_table+mark, propnum);
mark += 2;
- WriteInt16(p+mark, totallen);
+ WriteInt16(properties_table+mark, totallen);
mark += 2;
- WriteInt32(p+mark, datamarkstart);
+ WriteInt32(properties_table+mark, datamarkstart);
mark += 4;
- WriteInt16(p+mark, flags);
+ WriteInt16(properties_table+mark, flags);
mark += 2;
}
@@ -944,6 +1043,10 @@ static void manufacture_object_z(void)
segment_markers.enabled = FALSE;
directives.enabled = TRUE;
+ ensure_memory_list_available(&objectsz_memlist, no_objects+1);
+
+ objectsz[no_objects].symbol = full_object.symbol;
+
property_inheritance_z();
objectsz[no_objects].parent = parent_of_this_obj;
@@ -967,8 +1070,6 @@ static void manufacture_object_z(void)
j = write_property_block_z(shortname_buffer);
objectsz[no_objects].propsize = j;
- if (properties_table_size >= MAX_PROP_TABLE_SIZE)
- memoryerror("MAX_PROP_TABLE_SIZE",MAX_PROP_TABLE_SIZE);
if (current_defn_is_class)
for (i=0;i<6;i++) objectsz[no_objects].atts[i] = 0;
@@ -985,6 +1086,11 @@ static void manufacture_object_g(void)
segment_markers.enabled = FALSE;
directives.enabled = TRUE;
+ ensure_memory_list_available(&objectsg_memlist, no_objects+1);
+ ensure_memory_list_available(&objectatts_memlist, no_objects+1);
+
+ objectsg[no_objects].symbol = full_object_g.symbol;
+
property_inheritance_g();
objectsg[no_objects].parent = parent_of_this_obj;
@@ -1013,8 +1119,6 @@ static void manufacture_object_g(void)
objectsg[no_objects].propaddr = full_object_g.finalpropaddr;
objectsg[no_objects].propsize = j;
- if (properties_table_size >= MAX_PROP_TABLE_SIZE)
- memoryerror("MAX_PROP_TABLE_SIZE",MAX_PROP_TABLE_SIZE);
if (current_defn_is_class)
for (i=0;i");
}
+ trace_s(token_text, symbols[token_value].value, 2);
}
else
- { if (stypes[token_value]==INDIVIDUAL_PROPERTY_T)
- this_identifier_number = svals[token_value];
+ { if (symbols[token_value].type==INDIVIDUAL_PROPERTY_T)
+ this_identifier_number = symbols[token_value].value;
else
- { ebf_symbol_error("property name", token_text, typename(stypes[token_value]), slines[token_value]);
+ { ebf_symbol_error("property name", token_text, typename(symbols[token_value].type), symbols[token_value].line);
return;
}
}
@@ -1104,26 +1209,26 @@ static void properties_segment_z(int this_segment)
defined_this_segment[def_t_s++] = token_value;
if (individual_prop_table_size++ == 0)
- { full_object.pp[full_object.l].num = 3;
- full_object.pp[full_object.l].l = 1;
- full_object.pp[full_object.l].ao[0].value
- = individuals_length;
- full_object.pp[full_object.l].ao[0].type = LONG_CONSTANT_OT;
- full_object.pp[full_object.l].ao[0].marker = INDIVPT_MV;
+ {
+ int k=full_object.l++;
+ if (k >= 64)
+ fatalerror("More than 64 property entries in an object");
+ full_object.pp[k].num = 3;
+ full_object.pp[k].l = 1;
+ INITAOTV(&full_object.pp[k].ao[0], LONG_CONSTANT_OT, individuals_length);
+ full_object.pp[k].ao[0].marker = INDIVPT_MV;
i_m = individuals_length;
- full_object.l++;
}
+ ensure_memory_list_available(&individuals_table_memlist, i_m+3);
individuals_table[i_m] = this_identifier_number/256;
if (this_segment == PRIVATE_SEGMENT)
individuals_table[i_m] |= 0x80;
individuals_table[i_m+1] = this_identifier_number%256;
- if (module_switch)
- backpatch_zmachine(IDENT_MV, INDIVIDUAL_PROP_ZA, i_m);
individuals_table[i_m+2] = 0;
}
else
- { if (sflags[token_value] & UNKNOWN_SFLAG)
+ { if (symbols[token_value].flags & UNKNOWN_SFLAG)
{ error_named("No such property name as", token_text);
return;
}
@@ -1133,30 +1238,31 @@ not 'private':", token_text);
if (def_t_s >= defined_this_segment_size)
ensure_defined_this_segment(def_t_s*2);
defined_this_segment[def_t_s++] = token_value;
- property_number = svals[token_value];
+ property_number = symbols[token_value].value;
next_prop=full_object.l++;
+ if (next_prop >= 64)
+ fatalerror("More than 64 property entries in an object");
full_object.pp[next_prop].num = property_number;
}
for (i=0; i<(def_t_s-1); i++)
if (defined_this_segment[i] == token_value)
{ error_named("Property given twice in the same declaration:",
- (char *) symbs[token_value]);
+ symbols[token_value].name);
}
else
- if (svals[defined_this_segment[i]] == svals[token_value])
- { char error_b[128];
- sprintf(error_b,
+ if (symbols[defined_this_segment[i]].value == symbols[token_value].value)
+ {
+ error_fmt(
"Property given twice in the same declaration, because \
-the names '%s' and '%s' actually refer to the same property",
- (char *) symbs[defined_this_segment[i]],
- (char *) symbs[token_value]);
- error(error_b);
+the names \"%s\" and \"%s\" actually refer to the same property",
+ symbols[defined_this_segment[i]].name,
+ symbols[token_value].name);
}
property_name_symbol = token_value;
- sflags[token_value] |= USED_SFLAG;
+ symbols[token_value].flags |= USED_SFLAG;
length=0;
do
@@ -1176,18 +1282,24 @@ the names '%s' and '%s' actually refer to the same property",
warning ("'name' property should only contain dictionary words");
if ((token_type == SEP_TT) && (token_value == OPEN_SQUARE_SEP))
- { char embedded_name[80];
+ {
+ char *prefix, *sep, *sym;
+ sym = symbols[property_name_symbol].name;
if (current_defn_is_class)
- { sprintf(embedded_name,
- "%s::%s", classname_text,
- (char *) symbs[property_name_symbol]);
+ {
+ prefix = symbols[current_classname_symbol].name;
+ sep = "::";
}
else
- { sprintf(embedded_name,
- "%s.%s", objectname_text,
- (char *) symbs[property_name_symbol]);
+ {
+ prefix = current_object_name.data;
+ sep = ".";
}
- AO.value = parse_routine(NULL, TRUE, embedded_name, FALSE, -1);
+ ensure_memory_list_available(&embedded_function_name, strlen(prefix)+strlen(sep)+strlen(sym)+1);
+ sprintf(embedded_function_name.data, "%s%s%s", prefix, sep, sym);
+
+ /* parse_routine() releases lexer text! */
+ AO.value = parse_routine(NULL, TRUE, embedded_function_name.data, FALSE, -1);
AO.type = LONG_CONSTANT_OT;
AO.marker = IROUTINE_MV;
@@ -1217,7 +1329,7 @@ the names '%s' and '%s' actually refer to the same property",
{ if (length!=0)
{
if ((token_type == SYMBOL_TT)
- && (stypes[token_value]==PROPERTY_T))
+ && (symbols[token_value].type==PROPERTY_T))
{
/* This is not necessarily an error: it's possible
to imagine a property whose value is a list
@@ -1237,16 +1349,25 @@ the names '%s' and '%s' actually refer to the same property",
AO = parse_expression(ARRAY_CONTEXT);
}
+ /* length is in bytes here, but we report the limit in words. */
+
if (length == 64)
{ error_named("Limit (of 32 values) exceeded for property",
- (char *) symbs[property_name_symbol]);
+ symbols[property_name_symbol].name);
break;
}
+ if ((version_number==3) && (!individual_property) && length == 8)
+ { error_named("Limit (of 4 values) exceeded for property",
+ symbols[property_name_symbol].name);
+ break;
+ }
+
if (individual_property)
{ if (AO.marker != 0)
backpatch_zmachine(AO.marker, INDIVIDUAL_PROP_ZA,
i_m+3+length);
+ ensure_memory_list_available(&individuals_table_memlist, i_m+3+length+2);
individuals_table[i_m+3+length++] = AO.value/256;
individuals_table[i_m+3+length++] = AO.value%256;
}
@@ -1267,32 +1388,21 @@ the names '%s' and '%s' actually refer to the same property",
if (length == 0)
{ if (individual_property)
- { individuals_table[i_m+3+length++] = 0;
+ {
+ ensure_memory_list_available(&individuals_table_memlist, i_m+3+length+2);
+ individuals_table[i_m+3+length++] = 0;
individuals_table[i_m+3+length++] = 0;
}
else
- { full_object.pp[next_prop].ao[0].value = 0;
- full_object.pp[next_prop].ao[0].type = LONG_CONSTANT_OT;
- full_object.pp[next_prop].ao[0].marker = 0;
- length = 2;
- }
- }
-
- if ((version_number==3) && (!individual_property))
- { if (length > 8)
{
- warning_named("Version 3 limit of 4 values per property exceeded \
-(use -v5 to get 32), so truncating property",
- (char *) symbs[property_name_symbol]);
- length = 8;
+ INITAOTV(&full_object.pp[next_prop].ao[0], LONG_CONSTANT_OT, 0);
+ length = 2;
}
}
if (individual_property)
{
- if (individuals_length+length+3 > MAX_INDIV_PROP_TABLE_SIZE)
- memoryerror("MAX_INDIV_PROP_TABLE_SIZE",
- MAX_INDIV_PROP_TABLE_SIZE);
+ ensure_memory_list_available(&individuals_table_memlist, individuals_length+length+3);
individuals_table[i_m + 2] = length;
individuals_length += length+3;
i_m = individuals_length;
@@ -1332,14 +1442,14 @@ static void properties_segment_g(int this_segment)
}
if (token_type != SYMBOL_TT)
- { ebf_error("property name", token_text);
+ { ebf_curtoken_error("property name");
return;
}
- individual_property = (stypes[token_value] != PROPERTY_T);
+ individual_property = (symbols[token_value].type != PROPERTY_T);
if (individual_property)
- { if (sflags[token_value] & UNKNOWN_SFLAG)
+ { if (symbols[token_value].flags & UNKNOWN_SFLAG)
{ this_identifier_number = no_individual_properties++;
assign_symbol(token_value, this_identifier_number,
INDIVIDUAL_PROPERTY_T);
@@ -1353,12 +1463,13 @@ static void properties_segment_g(int this_segment)
debug_file_printf("");
}
+ trace_s(token_text, symbols[token_value].value, 2);
}
else
- { if (stypes[token_value]==INDIVIDUAL_PROPERTY_T)
- this_identifier_number = svals[token_value];
+ { if (symbols[token_value].type==INDIVIDUAL_PROPERTY_T)
+ this_identifier_number = symbols[token_value].value;
else
- { ebf_symbol_error("property name", token_text, typename(stypes[token_value]), slines[token_value]);
+ { ebf_symbol_error("property name", token_text, typename(symbols[token_value].type), symbols[token_value].line);
return;
}
}
@@ -1366,9 +1477,10 @@ static void properties_segment_g(int this_segment)
if (def_t_s >= defined_this_segment_size)
ensure_defined_this_segment(def_t_s*2);
defined_this_segment[def_t_s++] = token_value;
- property_number = svals[token_value];
+ property_number = symbols[token_value].value;
next_prop=full_object_g.numprops++;
+ ensure_memory_list_available(&full_object_g.props_memlist, next_prop+1);
full_object_g.props[next_prop].num = property_number;
full_object_g.props[next_prop].flags =
((this_segment == PRIVATE_SEGMENT) ? 1 : 0);
@@ -1377,7 +1489,7 @@ static void properties_segment_g(int this_segment)
full_object_g.props[next_prop].datalen = 0;
}
else
- { if (sflags[token_value] & UNKNOWN_SFLAG)
+ { if (symbols[token_value].flags & UNKNOWN_SFLAG)
{ error_named("No such property name as", token_text);
return;
}
@@ -1388,9 +1500,10 @@ not 'private':", token_text);
if (def_t_s >= defined_this_segment_size)
ensure_defined_this_segment(def_t_s*2);
defined_this_segment[def_t_s++] = token_value;
- property_number = svals[token_value];
+ property_number = symbols[token_value].value;
next_prop=full_object_g.numprops++;
+ ensure_memory_list_available(&full_object_g.props_memlist, next_prop+1);
full_object_g.props[next_prop].num = property_number;
full_object_g.props[next_prop].flags = 0;
full_object_g.props[next_prop].datastart = full_object_g.propdatasize;
@@ -1401,25 +1514,20 @@ not 'private':", token_text);
for (i=0; i<(def_t_s-1); i++)
if (defined_this_segment[i] == token_value)
{ error_named("Property given twice in the same declaration:",
- (char *) symbs[token_value]);
+ symbols[token_value].name);
}
else
- if (svals[defined_this_segment[i]] == svals[token_value])
- { char error_b[128];
- sprintf(error_b,
+ if (symbols[defined_this_segment[i]].value == symbols[token_value].value)
+ {
+ error_fmt(
"Property given twice in the same declaration, because \
-the names '%s' and '%s' actually refer to the same property",
- (char *) symbs[defined_this_segment[i]],
- (char *) symbs[token_value]);
- error(error_b);
+the names \"%s\" and \"%s\" actually refer to the same property",
+ symbols[defined_this_segment[i]].name,
+ symbols[token_value].name);
}
- if (full_object_g.numprops == MAX_OBJ_PROP_COUNT) {
- memoryerror("MAX_OBJ_PROP_COUNT",MAX_OBJ_PROP_COUNT);
- }
-
property_name_symbol = token_value;
- sflags[token_value] |= USED_SFLAG;
+ symbols[token_value].flags |= USED_SFLAG;
length=0;
do
@@ -1439,19 +1547,25 @@ the names '%s' and '%s' actually refer to the same property",
warning ("'name' property should only contain dictionary words");
if ((token_type == SEP_TT) && (token_value == OPEN_SQUARE_SEP))
- { char embedded_name[80];
+ {
+ char *prefix, *sep, *sym;
+ sym = symbols[property_name_symbol].name;
if (current_defn_is_class)
- { sprintf(embedded_name,
- "%s::%s", classname_text,
- (char *) symbs[property_name_symbol]);
+ {
+ prefix = symbols[current_classname_symbol].name;
+ sep = "::";
}
else
- { sprintf(embedded_name,
- "%s.%s", objectname_text,
- (char *) symbs[property_name_symbol]);
+ {
+ prefix = current_object_name.data;
+ sep = ".";
}
- AO.value = parse_routine(NULL, TRUE, embedded_name, FALSE, -1);
- AO.type = CONSTANT_OT;
+ ensure_memory_list_available(&embedded_function_name, strlen(prefix)+strlen(sep)+strlen(sym)+1);
+ sprintf(embedded_function_name.data, "%s%s%s", prefix, sep, sym);
+
+ INITAOT(&AO, CONSTANT_OT);
+ /* parse_routine() releases lexer text! */
+ AO.value = parse_routine(NULL, TRUE, embedded_function_name.data, FALSE, -1);
AO.marker = IROUTINE_MV;
directives.enabled = FALSE;
@@ -1480,7 +1594,7 @@ the names '%s' and '%s' actually refer to the same property",
{ if (length!=0)
{
if ((token_type == SYMBOL_TT)
- && (stypes[token_value]==PROPERTY_T))
+ && (symbols[token_value].type==PROPERTY_T))
{
/* This is not necessarily an error: it's possible
to imagine a property whose value is a list
@@ -1502,13 +1616,11 @@ the names '%s' and '%s' actually refer to the same property",
if (length == 32768) /* VENEER_CONSTRAINT_ON_PROP_TABLE_SIZE? */
{ error_named("Limit (of 32768 values) exceeded for property",
- (char *) symbs[property_name_symbol]);
+ symbols[property_name_symbol].name);
break;
}
- if (full_object_g.propdatasize >= MAX_OBJ_PROP_TABLE_SIZE) {
- memoryerror("MAX_OBJ_PROP_TABLE_SIZE",MAX_OBJ_PROP_TABLE_SIZE);
- }
+ ensure_memory_list_available(&full_object_g.propdata_memlist, full_object_g.propdatasize+1);
full_object_g.propdata[full_object_g.propdatasize++] = AO;
length += 1;
@@ -1526,9 +1638,8 @@ the names '%s' and '%s' actually refer to the same property",
if (length == 0)
{
assembly_operand AO;
- AO.value = 0;
- AO.type = CONSTANT_OT;
- AO.marker = 0;
+ INITAOTV(&AO, CONSTANT_OT, 0);
+ ensure_memory_list_available(&full_object_g.propdata_memlist, full_object_g.propdatasize+1);
full_object_g.propdata[full_object_g.propdatasize++] = AO;
length += 1;
}
@@ -1573,7 +1684,7 @@ static void attributes_segment(void)
|| (token_type == EOF_TT)
|| ((token_type == SEP_TT) && (token_value == SEMICOLON_SEP)))
{ if (!truth_state)
- ebf_error("attribute name after '~'", token_text);
+ ebf_curtoken_error("attribute name after '~'");
put_token_back(); return;
}
if ((token_type == SEP_TT) && (token_value == COMMA_SEP)) return;
@@ -1583,13 +1694,13 @@ static void attributes_segment(void)
}
if ((token_type != SYMBOL_TT)
- || (stypes[token_value] != ATTRIBUTE_T))
- { ebf_error("name of an already-declared attribute", token_text);
+ || (symbols[token_value].type != ATTRIBUTE_T))
+ { ebf_curtoken_error("name of an already-declared attribute");
return;
}
- attribute_number = svals[token_value];
- sflags[token_value] |= USED_SFLAG;
+ attribute_number = symbols[token_value].value;
+ symbols[token_value].flags |= USED_SFLAG;
if (!glulx_mode) {
bitmask = (1 << (7-attribute_number%8));
@@ -1623,7 +1734,7 @@ static void add_class_to_inheritance_list(int class_number)
to be translated into its actual class number: */
for (i=0;i 0)
- { sprintf(duplicate_name, "%s_1", shortname_buffer);
+ {
+ int namelen = strlen(shortname_buffer);
+ char *duplicate_name = my_malloc(namelen+16, "temporary storage for object duplicate names");
+ strcpy(duplicate_name, shortname_buffer);
for (n=1; (duplicates_to_make--) > 0; n++)
- { if (n>1)
- { int i = strlen(duplicate_name);
- while (duplicate_name[i] != '_') i--;
- sprintf(duplicate_name+i+1, "%d", n);
- }
+ {
+ sprintf(duplicate_name+namelen, "_%d", n);
make_object(FALSE, duplicate_name, class_number, class_number, -1);
}
+ my_free(&duplicate_name, "temporary storage for object duplicate names");
}
+
+ /* Finished building the class. */
+ current_classname_symbol = 0;
}
/* ------------------------------------------------------------------------- */
@@ -1936,16 +2061,13 @@ extern void make_object(int nearby_flag,
The last is used to create instances of a particular class. */
int i, tree_depth, internal_name_symbol = 0;
- char internal_name[64];
debug_location_beginning beginning_debug_location =
get_token_location_beginning();
directives.enabled = FALSE;
- if (no_objects==MAX_OBJECTS) memoryerror("MAX_OBJECTS", MAX_OBJECTS);
-
- sprintf(internal_name, "nameless_obj__%d", no_objects+1);
- objectname_text = internal_name;
+ ensure_memory_list_available(¤t_object_name, 32);
+ sprintf(current_object_name.data, "nameless_obj__%d", no_objects+1);
current_defn_is_class = FALSE;
@@ -1971,6 +2093,7 @@ extern void make_object(int nearby_flag,
}
}
+ ensure_memory_list_available(&shortname_buffer_memlist, 2);
sprintf(shortname_buffer, "?");
segment_markers.enabled = TRUE;
@@ -1983,15 +2106,15 @@ extern void make_object(int nearby_flag,
if (token_type == DQ_TT) textual_name = token_text;
else
{ if (token_type != SYMBOL_TT) {
- ebf_error("name for new object or its textual short name",
- token_text);
+ ebf_curtoken_error("name for new object or its textual short name");
}
- else if (!(sflags[token_value] & UNKNOWN_SFLAG)) {
- ebf_symbol_error("new object", token_text, typename(stypes[token_value]), slines[token_value]);
+ else if (!(symbols[token_value].flags & UNKNOWN_SFLAG)) {
+ ebf_symbol_error("new object", token_text, typename(symbols[token_value].type), symbols[token_value].line);
}
else
{ internal_name_symbol = token_value;
- strcpy(internal_name, token_text);
+ ensure_memory_list_available(¤t_object_name, strlen(token_text)+1);
+ strcpy(current_object_name.data, token_text);
}
}
@@ -2009,12 +2132,11 @@ extern void make_object(int nearby_flag,
}
else
{ if ((token_type != SYMBOL_TT)
- || (sflags[token_value] & UNKNOWN_SFLAG))
+ || (symbols[token_value].flags & UNKNOWN_SFLAG))
{ if (textual_name == NULL)
- ebf_error("parent object or the object's textual short name",
- token_text);
+ ebf_curtoken_error("parent object or the object's textual short name");
else
- ebf_error("parent object", token_text);
+ ebf_curtoken_error("parent object");
}
else goto SpecParent;
}
@@ -2025,15 +2147,15 @@ extern void make_object(int nearby_flag,
if (end_of_header()) goto HeaderPassed;
if (specified_parent != -1)
- ebf_error("body of object definition", token_text);
+ ebf_curtoken_error("body of object definition");
else
{ SpecParent:
- if ((stypes[token_value] == OBJECT_T)
- || (stypes[token_value] == CLASS_T))
- { specified_parent = svals[token_value];
- sflags[token_value] |= USED_SFLAG;
+ if ((symbols[token_value].type == OBJECT_T)
+ || (symbols[token_value].type == CLASS_T))
+ { specified_parent = symbols[token_value].value;
+ symbols[token_value].flags |= USED_SFLAG;
}
- else ebf_error("name of (the parent) object", token_text);
+ else ebf_curtoken_error("name of (the parent) object");
}
/* Now it really has to be the body of the definition. */
@@ -2041,7 +2163,7 @@ extern void make_object(int nearby_flag,
get_next_token_with_directives();
if (end_of_header()) goto HeaderPassed;
- ebf_error("body of object definition", token_text);
+ ebf_curtoken_error("body of object definition");
HeaderPassed:
if (specified_class == -1) put_token_back();
@@ -2049,20 +2171,31 @@ extern void make_object(int nearby_flag,
if (internal_name_symbol > 0)
assign_symbol(internal_name_symbol, no_objects + 1, OBJECT_T);
- if (listobjects_switch)
- printf("%3d \"%s\"\n", no_objects+1,
- (textual_name==NULL)?"(with no short name)":textual_name);
if (textual_name == NULL)
- { if (internal_name_symbol > 0)
+ {
+ if (internal_name_symbol > 0) {
+ ensure_memory_list_available(&shortname_buffer_memlist, strlen(symbols[internal_name_symbol].name)+4);
sprintf(shortname_buffer, "(%s)",
- (char *) symbs[internal_name_symbol]);
- else
+ symbols[internal_name_symbol].name);
+ }
+ else {
+ ensure_memory_list_available(&shortname_buffer_memlist, 32);
sprintf(shortname_buffer, "(%d)", no_objects+1);
+ }
}
else
- { if (strlen(textual_name)>765)
- error("Short name of object (in quotes) exceeded 765 characters");
- strncpy(shortname_buffer, textual_name, 765);
+ {
+ if (!glulx_mode) {
+ /* This check is only advisory. It's possible that a string of less than 765 characters will encode to more than 510 bytes. We'll double-check in write_property_block_z(). */
+ if (strlen(textual_name)>765)
+ error("Short name of object (in quotes) exceeded 765 Z-characters");
+ ensure_memory_list_available(&shortname_buffer_memlist, 766);
+ strncpy(shortname_buffer, textual_name, 765);
+ }
+ else {
+ ensure_memory_list_available(&shortname_buffer_memlist, strlen(textual_name)+1);
+ strcpy(shortname_buffer, textual_name);
+ }
}
if (specified_parent != -1)
@@ -2085,7 +2218,7 @@ extern void make_object(int nearby_flag,
{ int j = i, k = 0;
/* Metaclass or class objects cannot be '->' parents: */
- if ((!module_switch) && (i<4))
+ if (i<4)
continue;
if (!glulx_mode) {
@@ -2116,6 +2249,11 @@ extern void make_object(int nearby_flag,
}
initialise_full_object();
+ if (!glulx_mode)
+ full_object.symbol = internal_name_symbol;
+ else
+ full_object_g.symbol = internal_name_symbol;
+
if (instance_of != -1) add_class_to_inheritance_list(instance_of);
if (specified_class == -1) parse_body_of_definition();
@@ -2124,11 +2262,12 @@ extern void make_object(int nearby_flag,
if (debugfile_switch)
{ debug_file_printf("