X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=src%2Fsymbols.c;h=dc4eb53dbd5acbf615c7fa54e17b755be1d36e9f;hb=56a5292888e1d46fe3033cd1d5c636051692453f;hp=e8ac5b6446031572fd6bd4c4e3f90e89276b48b3;hpb=20cbfff96015938809d0e3da6cd0d83b76d27f14;p=inform.git diff --git a/src/symbols.c b/src/symbols.c index e8ac5b6..dc4eb53 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1,8 +1,8 @@ /* ------------------------------------------------------------------------- */ /* "symbols" : The symbols table; creating stock of reserved words */ /* */ -/* Part of Inform 6.41 */ -/* copyright (c) Graham Nelson 1993 - 2022 */ +/* 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 */ @@ -69,10 +69,13 @@ symbolinfo *symbols; /* Allocated up to no_symbols */ static memory_list symbols_memlist; symboldebuginfo *symbol_debug_info; /* Allocated up to no_symbols */ static memory_list symbol_debug_info_memlist; +static char *temp_symbol_buf; /* used in write_the_identifier_names() */ +static memory_list temp_symbol_buf_memlist; /* ------------------------------------------------------------------------- */ /* Memory to hold the text of symbol names: note that this memory is */ -/* allocated as needed in chunks of size SYMBOLS_CHUNK_SIZE. */ +/* allocated as needed in chunks of size SYMBOLS_CHUNK_SIZE. (Or */ +/* larger, if needed for a particularly enormous symbol.) */ /* ------------------------------------------------------------------------- */ #define SYMBOLS_CHUNK_SIZE (4096) @@ -237,10 +240,16 @@ extern int get_symbol_index(char *p) return -1; } -extern int symbol_index(char *p, int hashcode) +extern int symbol_index(char *p, int hashcode, int *created) { /* Return the index in the symbols array of symbol "p", creating a - new symbol with that name if it isn't already there. + new symbol with that name if it isn't already there. This + always returns a valid symbol index. + + The optional created argument receives TRUE if the symbol + was newly created. + + Pass in the hashcode of p if you know it, or -1 if you don't. New symbols are created with flag UNKNOWN_SFLAG, value 0x100 (a 2-byte quantity in Z-machine terms) and type CONSTANT_T. @@ -264,6 +273,7 @@ extern int symbol_index(char *p, int hashcode) { if (track_unused_routines) df_note_function_symbol(this); + if (created) *created = FALSE; return this; } if (new_entry > 0) break; @@ -273,7 +283,7 @@ extern int symbol_index(char *p, int hashcode) } while (this != -1); if (symdef_trace_setting) - printf("Encountered symbol %d '%s'\n", no_symbols, p); + printf("%s: Encountered symbol %d '%s'\n", current_location_text(), no_symbols, p); ensure_memory_list_available(&symbols_memlist, no_symbols+1); if (debugfile_switch) @@ -289,18 +299,19 @@ extern int symbol_index(char *p, int hashcode) } len = strlen(p); - if (symbols_free_space+len+1 >= symbols_ceiling) - { symbols_free_space - = my_malloc(SYMBOLS_CHUNK_SIZE, "symbol names chunk"); - symbols_ceiling = symbols_free_space + SYMBOLS_CHUNK_SIZE; + if (!symbols_free_space || symbols_free_space+len+1 >= symbols_ceiling) + { + /* Allocate a new chunk whose size is big enough for the current + symbol, or SYMBOLS_CHUNK_SIZE, whichever is greater. */ + int chunklen = SYMBOLS_CHUNK_SIZE; + if (chunklen < len+1) + chunklen = len+1; + symbols_free_space + = my_malloc(chunklen, "symbol names chunk"); + symbols_ceiling = symbols_free_space + chunklen; ensure_memory_list_available(&symbol_name_space_chunks_memlist, no_symbol_name_space_chunks+1); symbol_name_space_chunks[no_symbol_name_space_chunks++] = symbols_free_space; - if (symbols_free_space+len+1 >= symbols_ceiling) - { - /* This should be impossible, since SYMBOLS_CHUNK_SIZE > MAX_IDENTIFIER_LENGTH. */ - fatalerror("Symbol exceeds the maximum possible length"); - } } strcpy(symbols_free_space, p); @@ -322,17 +333,29 @@ extern int symbol_index(char *p, int hashcode) if (track_unused_routines) df_note_function_symbol(no_symbols); + if (created) *created = TRUE; return(no_symbols++); } -extern void end_symbol_scope(int k) +extern void end_symbol_scope(int k, int neveruse) { /* Remove the given symbol from the hash table, making it - invisible to symbol_index. This is used by the Undef directive. - If the symbol is not found, this silently does nothing. + invisible to symbol_index. This is used by the Undef directive + and put_token_back(). + + If you know the symbol has never been used, set neveruse and + it will be flagged as an error if it *is* used. + + If the symbol is not found in the hash table, this silently does + nothing. */ int j; + + symbols[k].flags |= UNHASHED_SFLAG; + if (neveruse) + symbols[k].flags |= DISCARDED_SFLAG; + j = hash_code_from_string(symbols[k].name); if (start_of_list[j] == k) { start_of_list[j] = symbols[k].next_entry; @@ -388,8 +411,8 @@ static void describe_flags(int flags) if (flags & USED_SFLAG) printf("(used) "); if (flags & DEFCON_SFLAG) printf("(Defaulted) "); if (flags & STUB_SFLAG) printf("(Stubbed) "); - if (flags & IMPORT_SFLAG) printf("(Imported) "); - if (flags & EXPORT_SFLAG) printf("(Exported) "); + if (flags & UNHASHED_SFLAG) printf("(not in hash chain) "); + if (flags & DISCARDED_SFLAG) printf("(removed, do not use) "); if (flags & ALIASED_SFLAG) printf("(aliased) "); if (flags & CHANGE_SFLAG) printf("(value will change) "); if (flags & SYSTEM_SFLAG) printf("(System) "); @@ -527,15 +550,22 @@ extern void issue_unused_warnings(void) } /* Now back to mark anything necessary as used */ - i = symbol_index("Main", -1); - if (!(symbols[i].flags & UNKNOWN_SFLAG)) symbols[i].flags |= USED_SFLAG; + i = get_symbol_index("Main"); + if (i >= 0 && !(symbols[i].flags & UNKNOWN_SFLAG)) { + symbols[i].flags |= USED_SFLAG; + } for (i=0;i"); debug_file_printf - ("##%s", idname_string); + ("##%s", temp_symbol_buf); debug_file_printf("%d", symbols[i].value); debug_file_printf(""); } action_name_strings[symbols[i].value] - = compile_string(idname_string, STRCTX_SYMBOL); + = compile_string(temp_symbol_buf, STRCTX_SYMBOL); } } for (i=0; i= 0 && symbols[ix].type == ROUTINE_T) { uint32 addr = symbols[ix].value * (glulx_mode ? 1 : scale_factor); tofunc = df_function_for_address(addr); if (tofunc) tofunc->usage |= DF_USAGE_MAIN; } - ix = symbol_index("Main", -1); - if (symbols[ix].type == ROUTINE_T) { + ix = get_symbol_index("Main"); + if (ix >= 0 && symbols[ix].type == ROUTINE_T) { uint32 addr = symbols[ix].value * (glulx_mode ? 1 : scale_factor); tofunc = df_function_for_address(addr); if (tofunc) @@ -1537,11 +1589,12 @@ extern void init_symbols_vars(void) symbols = NULL; start_of_list = NULL; symbol_debug_info = NULL; + temp_symbol_buf = NULL; symbol_name_space_chunks = NULL; no_symbol_name_space_chunks = 0; - symbols_free_space=NULL; - symbols_ceiling=NULL; + symbols_free_space = NULL; + symbols_ceiling = NULL; no_symbols = 0; @@ -1581,6 +1634,11 @@ extern void symbols_allocate_arrays(void) sizeof(symboldebuginfo), 6400, (void**)&symbol_debug_info, "symbol debug backpatch info"); } + + initialise_memory_list(&temp_symbol_buf_memlist, + sizeof(char), 64, (void**)&temp_symbol_buf, + "temporary symbol name"); + start_of_list = my_calloc(sizeof(int32), HASH_TAB_SIZE, "hash code list beginnings"); @@ -1634,6 +1692,8 @@ extern void symbols_free_arrays(void) { deallocate_memory_list(&symbol_debug_info_memlist); } + deallocate_memory_list(&temp_symbol_buf_memlist); + my_free(&start_of_list, "hash code list beginnings"); if (symbol_replacements)