From e536ce9e39cc1bfa82ecd1d6d73f874af655f9db Mon Sep 17 00:00:00 2001 From: Jason Self Date: Mon, 25 May 2020 15:52:13 -0700 Subject: [PATCH] Update to commit d9e45a19b61c54bc804232fdc67485b84c7af8e9 dated May 21, 2020. These changes are similiarly relicensed to GPL per Section 4(c)(ii) of the Artistic License 2.0. --- src/arrays.c | 236 ++++++++++++++++++++++++++++++++++++------------- src/asm.c | 2 +- src/bpatch.c | 21 ++++- src/chars.c | 2 +- src/directs.c | 2 +- src/errors.c | 2 +- src/expressc.c | 33 ++++--- src/expressp.c | 5 +- src/files.c | 51 ++++++++++- src/header.h | 31 ++++--- src/inform.c | 2 +- src/lexer.c | 4 +- src/linker.c | 2 +- src/memory.c | 11 ++- src/objects.c | 2 +- src/states.c | 12 +-- src/symbols.c | 3 +- src/syntax.c | 2 +- src/tables.c | 46 ++++++++-- src/text.c | 2 +- src/veneer.c | 8 +- src/verbs.c | 2 +- 22 files changed, 360 insertions(+), 121 deletions(-) diff --git a/src/arrays.c b/src/arrays.c index 93cc31e..fc4f7af 100644 --- a/src/arrays.c +++ b/src/arrays.c @@ -3,7 +3,7 @@ /* likewise global variables, which are in some ways a */ /* simpler form of the same thing. */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ @@ -29,6 +29,8 @@ /* */ /* int dynamic_array_area[] Initial values for the bytes of */ /* the dynamic array area */ +/* int static_array_area[] Initial values for the bytes of */ +/* the static array area */ /* int32 global_initial_value[n] The initialised value of the nth */ /* global variable (counting 0 - 239) */ /* */ @@ -41,6 +43,10 @@ /* In Glulx, that 240 is changed to MAX_GLOBAL_VAR_NUMBER, and we take */ /* correspondingly more space for the globals. This *really* ought to be */ /* split into two segments. */ +/* */ +/* We can also store arrays (but not globals) into static memory (ROM). */ +/* The storage for these goes, unsurprisingly, into static_array_area -- */ +/* a separate allocation of MAX_STATIC_DATA bytes. */ /* ------------------------------------------------------------------------- */ int *dynamic_array_area; /* See above */ int32 *global_initial_value; @@ -54,9 +60,15 @@ int no_globals; /* Number of global variables used int dynamic_array_area_size; /* Size in bytes */ +int *static_array_area; +int static_array_area_size; + int no_arrays; int32 *array_symbols; -int *array_sizes, *array_types; +int *array_sizes, *array_types, *array_locs; +/* array_sizes[N] gives the length of array N; array_types[N] is one of + the constants BYTE_ARRAY, WORD_ARRAY, etc; array_locs[N] is true for + static arrays, false for dynamic arrays. */ static int array_entry_size, /* 1 for byte array, 2 for word array */ array_base; /* Offset in dynamic array area of the @@ -70,60 +82,89 @@ static int array_entry_size, /* 1 for byte array, 2 for word array */ /* In Glulx, of course, that will be 4 instead of 2. */ -extern void finish_array(int32 i) +extern void finish_array(int32 i, int is_static) { + int *area; + int area_size; + + if (!is_static) { + area = dynamic_array_area; + area_size = dynamic_array_area_size; + } + else { + area = static_array_area; + area_size = static_array_area_size; + } + /* Write the array size into the 0th byte/word of the array, if it's a "table" or "string" array */ if (!glulx_mode) { - if (array_base!=dynamic_array_area_size) - { if (dynamic_array_area_size-array_base==2) - { dynamic_array_area[array_base] = i/256; - dynamic_array_area[array_base+1] = i%256; + if (array_base != area_size) + { if (area_size-array_base==2) + { area[array_base] = i/256; + area[array_base+1] = i%256; } else { if (i>=256) error("A 'string' array can have at most 256 entries"); - dynamic_array_area[array_base] = i; + area[array_base] = i; } } } else { - if (array_base!=dynamic_array_area_size) - { if (dynamic_array_area_size-array_base==4) + if (array_base != area_size) + { if (area_size-array_base==4) { - dynamic_array_area[array_base] = (i >> 24) & 0xFF; - dynamic_array_area[array_base+1] = (i >> 16) & 0xFF; - dynamic_array_area[array_base+2] = (i >> 8) & 0xFF; - dynamic_array_area[array_base+3] = (i) & 0xFF; + area[array_base] = (i >> 24) & 0xFF; + area[array_base+1] = (i >> 16) & 0xFF; + area[array_base+2] = (i >> 8) & 0xFF; + area[array_base+3] = (i) & 0xFF; } else { if (i>=256) error("A 'string' array can have at most 256 entries"); - dynamic_array_area[array_base] = i; + area[array_base] = i; } } } - /* Move on the dynamic array size so that it now points to the next - available free space */ + /* Move on the static/dynamic array size so that it now points to the + next available free space */ - dynamic_array_area_size += i*array_entry_size; + if (!is_static) { + dynamic_array_area_size += i*array_entry_size; + } + else { + static_array_area_size += i*array_entry_size; + } } -extern void array_entry(int32 i, assembly_operand VAL) +extern void array_entry(int32 i, int is_static, assembly_operand VAL) { + int *area; + int area_size; + + if (!is_static) { + area = dynamic_array_area; + area_size = dynamic_array_area_size; + } + else { + area = static_array_area; + area_size = static_array_area_size; + } + if (!glulx_mode) { /* Array entry i (initial entry has i=0) is set to Z-machine value j */ - if (dynamic_array_area_size+(i+1)*array_entry_size > MAX_STATIC_DATA) + if (area_size+(i+1)*array_entry_size > MAX_STATIC_DATA) memoryerror("MAX_STATIC_DATA", MAX_STATIC_DATA); if (array_entry_size==1) - { dynamic_array_area[dynamic_array_area_size+i] = (VAL.value)%256; + { area[area_size+i] = (VAL.value)%256; if (VAL.marker != 0) error("Entries in byte arrays and strings must be known constants"); @@ -135,21 +176,30 @@ extern void array_entry(int32 i, assembly_operand VAL) warning("Entry in '->', 'string' or 'buffer' array not in range 0 to 255"); } else - { dynamic_array_area[dynamic_array_area_size + 2*i] = (VAL.value)/256; - dynamic_array_area[dynamic_array_area_size + 2*i+1] = (VAL.value)%256; - if (VAL.marker != 0) - backpatch_zmachine(VAL.marker, DYNAMIC_ARRAY_ZA, - dynamic_array_area_size + 2*i); + { + int32 addr = area_size + 2*i; + area[addr] = (VAL.value)/256; + area[addr+1] = (VAL.value)%256; + if (VAL.marker != 0) { + if (!is_static) { + backpatch_zmachine(VAL.marker, DYNAMIC_ARRAY_ZA, + addr); + } + else { + backpatch_zmachine(VAL.marker, STATIC_ARRAY_ZA, + addr); + } + } } } else { /* Array entry i (initial entry has i=0) is set to value j */ - if (dynamic_array_area_size+(i+1)*array_entry_size > MAX_STATIC_DATA) + if (area_size+(i+1)*array_entry_size > MAX_STATIC_DATA) memoryerror("MAX_STATIC_DATA", MAX_STATIC_DATA); if (array_entry_size==1) - { dynamic_array_area[dynamic_array_area_size+i] = (VAL.value) & 0xFF; + { area[area_size+i] = (VAL.value) & 0xFF; if (VAL.marker != 0) error("Entries in byte arrays and strings must be known constants"); @@ -161,13 +211,33 @@ extern void array_entry(int32 i, assembly_operand VAL) warning("Entry in '->', 'string' or 'buffer' array not in range 0 to 255"); } else if (array_entry_size==4) - { dynamic_array_area[dynamic_array_area_size + 4*i] = (VAL.value >> 24) & 0xFF; - dynamic_array_area[dynamic_array_area_size + 4*i+1] = (VAL.value >> 16) & 0xFF; - dynamic_array_area[dynamic_array_area_size + 4*i+2] = (VAL.value >> 8) & 0xFF; - dynamic_array_area[dynamic_array_area_size + 4*i+3] = (VAL.value) & 0xFF; - if (VAL.marker != 0) - backpatch_zmachine(VAL.marker, ARRAY_ZA, - dynamic_array_area_size - 4*MAX_GLOBAL_VARIABLES + 4*i); + { + int32 addr = area_size + 4*i; + area[addr] = (VAL.value >> 24) & 0xFF; + area[addr+1] = (VAL.value >> 16) & 0xFF; + area[addr+2] = (VAL.value >> 8) & 0xFF; + area[addr+3] = (VAL.value) & 0xFF; + if (VAL.marker != 0) { + if (!is_static) { + backpatch_zmachine(VAL.marker, DYNAMIC_ARRAY_ZA, + addr - 4*MAX_GLOBAL_VARIABLES); + } + else { + /* We can't use backpatch_zmachine() because that only applies to RAM. Instead we add an entry to staticarray_backpatch_table. + A backpatch entry is five bytes: *_MV followed by the array offset (in static array area). */ + write_byte_to_memory_block(&staticarray_backpatch_table, + staticarray_backpatch_size++, + VAL.marker); + write_byte_to_memory_block(&staticarray_backpatch_table, + staticarray_backpatch_size++, ((addr >> 24) & 0xFF)); + write_byte_to_memory_block(&staticarray_backpatch_table, + staticarray_backpatch_size++, ((addr >> 16) & 0xFF)); + write_byte_to_memory_block(&staticarray_backpatch_table, + staticarray_backpatch_size++, ((addr >> 8) & 0xFF)); + write_byte_to_memory_block(&staticarray_backpatch_table, + staticarray_backpatch_size++, (addr & 0xFF)); + } + } } else { @@ -183,7 +253,7 @@ extern void array_entry(int32 i, assembly_operand VAL) /* | = */ /* | */ /* */ -/* Array */ +/* Array [static] */ /* */ /* where an array specification is: */ /* */ @@ -191,6 +261,9 @@ extern void array_entry(int32 i, assembly_operand VAL) /* | --> | ... */ /* | string | [ [,] [;] ... ]; */ /* | table */ +/* | buffer */ +/* */ +/* The "static" keyword (arrays only) places the array in static memory. */ /* */ /* ------------------------------------------------------------------------- */ @@ -214,6 +287,7 @@ extern void make_global(int array_flag, int name_only) int32 i; int array_type, data_type; + int is_static = FALSE; assembly_operand AO; int32 global_symbol; @@ -248,13 +322,32 @@ extern void make_global(int array_flag, int name_only) if ((!array_flag) && (sflags[i] & USED_SFLAG)) error_named("Variable must be defined before use:", token_text); + directive_keywords.enabled = TRUE; + get_next_token(); + directive_keywords.enabled = FALSE; + if ((token_type==DIR_KEYWORD_TT)&&(token_value==STATIC_DK)) { + if (array_flag) { + is_static = TRUE; + } + else { + error("Global variables cannot be static"); + } + } + else { + put_token_back(); + } + if (array_flag) - { - if (!glulx_mode) - assign_symbol(i, dynamic_array_area_size, ARRAY_T); - else - assign_symbol(i, - dynamic_array_area_size - 4*MAX_GLOBAL_VARIABLES, ARRAY_T); + { if (!is_static) { + if (!glulx_mode) + assign_symbol(i, dynamic_array_area_size, ARRAY_T); + else + assign_symbol(i, + dynamic_array_area_size - 4*MAX_GLOBAL_VARIABLES, ARRAY_T); + } + else { + assign_symbol(i, static_array_area_size, STATIC_ARRAY_T); + } if (no_arrays == MAX_ARRAYS) memoryerror("MAX_ARRAYS", MAX_ARRAYS); array_symbols[no_arrays] = i; @@ -313,6 +406,7 @@ extern void make_global(int array_flag, int name_only) if (!array_flag) { + /* is_static is always false in this case */ if ((token_type == SEP_TT) && (token_value == SETEQUALS_SEP)) { AO = parse_expression(CONSTANT_CONTEXT); if (!glulx_mode) { @@ -418,15 +512,29 @@ extern void make_global(int array_flag, int name_only) case ASCII_AI: obsolete_warning("use '->' instead of 'initstr'"); break; } - array_base = dynamic_array_area_size; - /* Leave room to write the array size in later, if string/table array */ - + + int extraspace = 0; if ((array_type==STRING_ARRAY) || (array_type==TABLE_ARRAY)) - dynamic_array_area_size += array_entry_size; + extraspace += array_entry_size; if (array_type==BUFFER_ARRAY) - dynamic_array_area_size += WORDSIZE; + extraspace += WORDSIZE; + + int orig_area_size; + + if (!is_static) { + orig_area_size = dynamic_array_area_size; + array_base = dynamic_array_area_size; + dynamic_array_area_size += extraspace; + } + else { + orig_area_size = static_array_area_size; + array_base = static_array_area_size; + static_array_area_size += extraspace; + } + array_types[no_arrays] = array_type; + array_locs[no_arrays] = is_static; switch(data_type) { @@ -454,7 +562,7 @@ extern void make_global(int array_flag, int name_only) } } - { for (i=0; i"); @@ -579,9 +687,10 @@ advance as part of 'Zcharacter table':", unicode); debug_file_printf(""); write_debug_array_backpatch(svals[global_symbol]); debug_file_printf(""); + int32 new_area_size = (!is_static ? dynamic_array_area_size : static_array_area_size); debug_file_printf ("%d", - dynamic_array_area_size - array_base); + new_area_size - array_base); debug_file_printf ("%d", array_entry_size); @@ -602,8 +711,9 @@ advance as part of 'Zcharacter table':", unicode); extern int32 begin_table_array(void) { - /* The "box" statement needs to be able to construct (static) table - arrays of strings like this */ + /* The "box" statement needs to be able to construct table + arrays of strings like this. (Static data, but we create a dynamic + array for maximum backwards compatibility.) */ array_base = dynamic_array_area_size; array_entry_size = WORDSIZE; @@ -621,7 +731,8 @@ extern int32 begin_table_array(void) extern int32 begin_word_array(void) { /* The "random(a, b, ...)" function needs to be able to construct - (static) word arrays like this */ + word arrays like this. (Static data, but we create a dynamic + array for maximum backwards compatibility.) */ array_base = dynamic_array_area_size; array_entry_size = WORDSIZE; @@ -638,6 +749,7 @@ extern int32 begin_word_array(void) extern void init_arrays_vars(void) { dynamic_array_area = NULL; + static_array_area = NULL; global_initial_value = NULL; array_sizes = NULL; array_symbols = NULL; array_types = NULL; } @@ -649,23 +761,29 @@ extern void arrays_begin_pass(void) else no_globals=11; dynamic_array_area_size = WORDSIZE * MAX_GLOBAL_VARIABLES; + static_array_area_size = 0; } extern void arrays_allocate_arrays(void) { dynamic_array_area = my_calloc(sizeof(int), MAX_STATIC_DATA, - "static data"); + "dynamic array data"); + static_array_area = my_calloc(sizeof(int), MAX_STATIC_DATA, + "static array data"); array_sizes = my_calloc(sizeof(int), MAX_ARRAYS, "array sizes"); array_types = my_calloc(sizeof(int), MAX_ARRAYS, "array types"); + array_locs = my_calloc(sizeof(int), MAX_ARRAYS, "array locations"); array_symbols = my_calloc(sizeof(int32), MAX_ARRAYS, "array symbols"); global_initial_value = my_calloc(sizeof(int32), MAX_GLOBAL_VARIABLES, "global values"); } extern void arrays_free_arrays(void) -{ my_free(&dynamic_array_area, "static data"); +{ my_free(&dynamic_array_area, "dynamic array data"); + my_free(&static_array_area, "static array data"); my_free(&global_initial_value, "global values"); my_free(&array_sizes, "array sizes"); - my_free(&array_types, "array sizes"); + my_free(&array_types, "array types"); + my_free(&array_locs, "array locations"); my_free(&array_symbols, "array sizes"); } diff --git a/src/asm.c b/src/asm.c index a5444fd..3467100 100644 --- a/src/asm.c +++ b/src/asm.c @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- */ /* "asm" : The Inform assembler */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ diff --git a/src/bpatch.c b/src/bpatch.c index ccc87ba..43078d2 100644 --- a/src/bpatch.c +++ b/src/bpatch.c @@ -2,7 +2,7 @@ /* "bpatch" : Keeps track of, and finally acts on, backpatch markers, */ /* correcting symbol values not known at compilation time */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ @@ -23,8 +23,10 @@ #include "header.h" -memory_block zcode_backpatch_table, zmachine_backpatch_table; -int32 zcode_backpatch_size, zmachine_backpatch_size; +memory_block zcode_backpatch_table, staticarray_backpatch_table, + zmachine_backpatch_table; +int32 zcode_backpatch_size, staticarray_backpatch_size, + zmachine_backpatch_size; /* ------------------------------------------------------------------------- */ /* The mending operation */ @@ -46,6 +48,8 @@ static int32 backpatch_value_z(int32 value) value += strings_offset/scale_factor; break; case ARRAY_MV: value += variables_offset; break; + case STATIC_ARRAY_MV: + value += static_arrays_offset; break; case IROUTINE_MV: if (OMIT_UNUSED_ROUTINES) value = df_stripped_address_for_address(value); @@ -155,6 +159,7 @@ static int32 backpatch_value_z(int32 value) value += code_offset/scale_factor; break; case ARRAY_T: value += variables_offset; break; + case STATIC_ARRAY_T: value += static_arrays_offset; break; } } break; @@ -196,6 +201,8 @@ static int32 backpatch_value_g(int32 value) break; case ARRAY_MV: value += arrays_offset; break; + case STATIC_ARRAY_MV: + value += static_arrays_offset; break; case VARIABLE_MV: value = variables_offset + (4*value); break; case OBJECT_MV: @@ -303,6 +310,7 @@ static int32 backpatch_value_g(int32 value) value += code_offset; break; case ARRAY_T: value += arrays_offset; break; + case STATIC_ARRAY_T: value += static_arrays_offset; break; case OBJECT_T: case CLASS_T: value = object_tree_offset + @@ -425,6 +433,7 @@ extern void backpatch_zmachine_image_z(void) case PROP_ZA: addr = prop_values_offset; break; case INDIVIDUAL_PROP_ZA: addr = individuals_offset; break; case DYNAMIC_ARRAY_ZA: addr = variables_offset; break; + case STATIC_ARRAY_ZA: addr = static_arrays_offset; break; default: if (no_link_errors == 0) if (compiler_error("Illegal area to backpatch")) @@ -471,8 +480,9 @@ extern void backpatch_zmachine_image_g(void) case PROP_DEFAULTS_ZA: addr = prop_defaults_offset+4; break; case PROP_ZA: addr = prop_values_offset; break; case INDIVIDUAL_PROP_ZA: addr = individuals_offset; break; - case ARRAY_ZA: addr = arrays_offset; break; + case DYNAMIC_ARRAY_ZA: addr = arrays_offset; break; case GLOBALVAR_ZA: addr = variables_offset; break; + /* STATIC_ARRAY_ZA is in ROM and therefore not handled here */ default: if (no_link_errors == 0) if (compiler_error("Illegal area to backpatch")) @@ -505,11 +515,13 @@ extern void backpatch_zmachine_image_g(void) extern void init_bpatch_vars(void) { initialise_memory_block(&zcode_backpatch_table); + initialise_memory_block(&staticarray_backpatch_table); initialise_memory_block(&zmachine_backpatch_table); } extern void bpatch_begin_pass(void) { zcode_backpatch_size = 0; + staticarray_backpatch_size = 0; zmachine_backpatch_size = 0; } @@ -519,6 +531,7 @@ extern void bpatch_allocate_arrays(void) extern void bpatch_free_arrays(void) { deallocate_memory_block(&zcode_backpatch_table); + deallocate_memory_block(&staticarray_backpatch_table); deallocate_memory_block(&zmachine_backpatch_table); } diff --git a/src/chars.c b/src/chars.c index e91e9c1..701d14e 100644 --- a/src/chars.c +++ b/src/chars.c @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- */ /* "chars" : Character set mappings and the Z-machine alphabet table */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ diff --git a/src/directs.c b/src/directs.c index d3b7f32..b802d5e 100644 --- a/src/directs.c +++ b/src/directs.c @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- */ /* "directs" : Directives (# commands) */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ diff --git a/src/errors.c b/src/errors.c index 8a4d288..73fa1be 100644 --- a/src/errors.c +++ b/src/errors.c @@ -2,7 +2,7 @@ /* "errors" : Warnings, errors and fatal errors */ /* (with error throwback code for RISC OS machines) */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ diff --git a/src/expressc.c b/src/expressc.c index e6db119..876804b 100644 --- a/src/expressc.c +++ b/src/expressc.c @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- */ /* "expressc" : The expression code generator */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ @@ -451,7 +451,7 @@ static void access_memory_z(int oc, assembly_operand AO1, assembly_operand AO2, index_ao; int x = 0, y = 0, byte_flag = FALSE, read_flag = FALSE, from_module = FALSE; - if (AO1.marker == ARRAY_MV) + if (AO1.marker == ARRAY_MV || AO1.marker == STATIC_ARRAY_MV) { INITAO(&zero_ao); @@ -465,10 +465,16 @@ static void access_memory_z(int oc, assembly_operand AO1, assembly_operand AO2, size_ao = zero_ao; size_ao.value = -1; for (x=0; x> 24) & 0xFF); + sf_put((val >> 16) & 0xFF); + sf_put((val >> 8) & 0xFF); + sf_put((val) & 0xFF); + size += 4; + } + + /* Flush out the last bit of static_array_area, after the last backpatch marker. */ + offset = static_array_area_size; + while (jx ln2) ln2 = j; } put_token_back(); - array_entry(ln++,parse_expression(CONSTANT_CONTEXT)); + array_entry(ln++, FALSE, parse_expression(CONSTANT_CONTEXT)); } while (TRUE); - finish_array(ln); + finish_array(ln, FALSE); if (ln == 0) error("No lines of text given for 'box' display"); @@ -1815,9 +1815,9 @@ static void parse_statement_g(int break_label, int continue_label) if (j > ln2) ln2 = j; } put_token_back(); - array_entry(ln++,parse_expression(CONSTANT_CONTEXT)); + array_entry(ln++, FALSE, parse_expression(CONSTANT_CONTEXT)); } while (TRUE); - finish_array(ln); + finish_array(ln, FALSE); if (ln == 0) error("No lines of text given for 'box' display"); diff --git a/src/symbols.c b/src/symbols.c index 3263166..4d437ac 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- */ /* "symbols" : The symbols table; creating stock of reserved words */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ @@ -297,6 +297,7 @@ extern char *typename(int type) case LABEL_T: return("Label"); case GLOBAL_VARIABLE_T: return("Global variable"); case ARRAY_T: return("Array"); + case STATIC_ARRAY_T: return("Static array"); case CONSTANT_T: return("Defined constant"); case ATTRIBUTE_T: return("Attribute"); case PROPERTY_T: return("Property"); diff --git a/src/syntax.c b/src/syntax.c index 2486dec..0896af9 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- */ /* "syntax" : Syntax analyser and compiler */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ diff --git a/src/tables.c b/src/tables.c index 103f6f9..df3cdfb 100644 --- a/src/tables.c +++ b/src/tables.c @@ -3,7 +3,7 @@ /* end of dynamic memory, gluing together all the required */ /* tables. */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ @@ -32,7 +32,7 @@ uchar *zmachine_paged_memory; /* Where we shall store the story file at the end of the compilation pass */ /* In Glulx, zmachine_paged_memory contains all of RAM -- i.e. all but - the header, the code, and the static strings. */ + the header, the code, the static arrays, and the static strings. */ /* ------------------------------------------------------------------------- */ /* Offsets of various areas in the Z-machine: these are set to nominal */ @@ -72,7 +72,8 @@ int32 code_offset, routine_flags_array_offset, global_names_offset, global_flags_array_offset, - array_flags_array_offset; + array_flags_array_offset, + static_arrays_offset; int32 arrays_offset, object_tree_offset, grammar_table_offset, @@ -191,6 +192,8 @@ static int32 rough_size_of_paged_memory_z(void) total += (subtract_pointers(dictionary_top, dictionary)) /* dictionary */ + ((module_switch)?30:0); /* module map */ + total += static_array_area_size; /* static arrays */ + total += scale_factor*0x100 /* maximum null bytes before code */ + 1000; /* fudge factor (in case the above is wrong) */ @@ -201,7 +204,7 @@ static int32 rough_size_of_paged_memory_g(void) { /* This function calculates a modest over-estimate of the amount of memory required to store the machine's paged memory area - (that is, everything up to the start of the code area). */ + (that is, everything past the start of RAM). */ int32 total; @@ -246,7 +249,8 @@ static void construct_storyfile_z(void) int32 globals_at=0, link_table_at=0, dictionary_at=0, actions_at=0, preactions_at=0, abbrevs_at=0, prop_defaults_at=0, object_tree_at=0, object_props_at=0, map_of_module=0, grammar_table_at=0, charset_at=0, headerext_at=0, - terminating_chars_at=0, unicode_at=0, id_names_length=0; + terminating_chars_at=0, unicode_at=0, id_names_length=0, + static_arrays_at=0; int skip_backpatching = FALSE; char *output_called = (module_switch)?"module":"story file"; @@ -609,6 +613,12 @@ table format requested (producing number 2 format instead)"); mark += 30; } + /* ------------------------ Static Arrays ----------------------------- */ + + static_arrays_at = mark; + for (i=0; i= 256, hence long constants) */ @@ -706,6 +716,7 @@ or less."); prop_values_offset = object_props_at; static_memory_offset = grammar_table_at; grammar_table_offset = grammar_table_at; + static_arrays_offset = static_arrays_at; if (extend_memory_map) { extend_offset=256; @@ -1142,6 +1153,11 @@ printf(" + - - - - - - - - - - + %05lx\n", (long int) map_of_module); printf(" | map of module addrs |\n"); } +if (static_array_area_size) +{ +printf(" +---------------------+ %05lx\n", (long int) static_arrays_at); +printf(" | static arrays |\n"); +} printf(" +=====================+ %05lx\n", (long int) Write_Code_At); printf("Above | Z-code |\n"); printf("readable+---------------------+ %05lx\n", @@ -1196,7 +1212,7 @@ static void construct_storyfile_g(void) int32 globals_at, dictionary_at, actions_at, preactions_at, abbrevs_at, prop_defaults_at, object_tree_at, object_props_at, grammar_table_at, charset_at, headerext_at, - unicode_at, arrays_at; + unicode_at, arrays_at, static_arrays_at; int32 threespaces, code_length; char *output_called = (module_switch)?"module":"story file"; @@ -1256,8 +1272,10 @@ static void construct_storyfile_g(void) Write_Strings_At = Write_Code_At + code_length; strings_length = compression_table_size + compression_string_size; + static_arrays_at = Write_Strings_At + strings_length; + /* Now figure out where RAM starts. */ - Write_RAM_At = Write_Strings_At + strings_length; + Write_RAM_At = static_arrays_at + static_array_area_size; /* The Write_RAM_At boundary must be a multiple of GPAGESIZE. */ while (Write_RAM_At % GPAGESIZE) Write_RAM_At++; @@ -1568,6 +1586,7 @@ table format requested (producing number 2 format instead)"); code_offset = Write_Code_At; strings_offset = Write_Strings_At; + static_arrays_offset = static_arrays_at; /* --------------------------- The Header ----------------------------- */ @@ -1739,9 +1758,10 @@ Out: %s %s %d.%c%c%c%c%c%c (%ld%sK long):\n", write_debug_section("string decoding table", Write_Strings_At); write_debug_section("strings area", Write_Strings_At + compression_table_size); - if (Write_Strings_At + strings_length < Write_RAM_At) + write_debug_section("static array space", static_arrays_at); + if (static_arrays_at + static_array_area_size < Write_RAM_At) { write_debug_section - ("zero padding", Write_Strings_At + strings_length); + ("zero padding", static_arrays_at + static_array_area_size); } if (globals_at) { compiler_error("Failed assumption that globals are at start of " @@ -1784,6 +1804,12 @@ printf(" | string decode table |\n"); printf(" + - - - - - - - - - - + %06lx\n", (long int) Write_Strings_At + compression_table_size); printf(" | strings |\n"); + if (static_array_area_size) + { +printf(" +---------------------+ %06lx\n", + (long int) (static_arrays_at)); +printf(" | static arrays |\n"); + } printf(" +=====================+ %06lx\n", (long int) (Write_RAM_At+globals_at)); printf("Dynamic | global variables |\n"); @@ -1911,6 +1937,7 @@ extern void init_tables_vars(void) identifier_names_offset=0x800; class_numbers_offset = 0x800; arrays_offset = 0x0800; /* only used in Glulx, but might as well set */ + static_arrays_offset = 0x0800; } else { code_offset = 0x12345; @@ -1924,6 +1951,7 @@ extern void init_tables_vars(void) individuals_offset=0x12345; identifier_names_offset=0x12345; class_numbers_offset = 0x12345; + static_arrays_offset = 0x12345; } } diff --git a/src/text.c b/src/text.c index cd2fcd8..3161238 100644 --- a/src/text.c +++ b/src/text.c @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- */ /* "text" : Text translation, the abbreviations optimiser, the dictionary */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ diff --git a/src/veneer.c b/src/veneer.c index 2f70159..519e085 100644 --- a/src/veneer.c +++ b/src/veneer.c @@ -3,7 +3,7 @@ /* by the compiler (e.g. DefArt) which the program doesn't */ /* provide */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ @@ -246,7 +246,11 @@ static VeneerRoutine VRs_z[VENEER_ROUTINES] = { if (identifier >= 1 && identifier < 64 && obj.#identifier <= 2)\ return obj.identifier;\ RT__Err(\"read\", obj, identifier); return; }\ + #IFV3;\ + if (obj..#identifier > 2) RT__Err(\"read\", obj, identifier);\ + #IFNOT;\ if (obj..#identifier > 2) RT__Err(\"read\", obj, identifier, 2);\ + #ENDIF;\ return x-->0;\ ]", "", "", "", "", "" }, @@ -2244,7 +2248,7 @@ static void compile_symbol_table_routine(void) AO3.marker = 0; assemblez_store(temp_var3, AO3); AO3.value = svals[array_symbols[j]]; - AO3.marker = ARRAY_MV; + AO3.marker = (!array_locs[j] ? ARRAY_MV : STATIC_ARRAY_MV); assemblez_1(ret_zc, AO3); assemble_label_no(nl); } diff --git a/src/verbs.c b/src/verbs.c index 1116e09..f9f13be 100644 --- a/src/verbs.c +++ b/src/verbs.c @@ -2,7 +2,7 @@ /* "verbs" : Manages actions and grammar tables; parses the directives */ /* Verb and Extend. */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ +/* Copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* This file is part of Inform. */ /* */ -- 2.31.1