From 5910081651e6b53021b6c648a06a309775cb571c Mon Sep 17 00:00:00 2001 From: marcobaye Date: Mon, 26 Feb 2024 23:54:10 +0000 Subject: [PATCH] more cleanup and preparations for new features git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@349 4df02467-bbd4-4a76-a152-e7ce94205b78 --- docs/Errors.txt | 13 +++---------- src/acme.c | 11 +++++------ src/config.h | 11 ++++++++++- src/global.c | 27 +++++++++++++++++++------- src/global.h | 8 +++++++- src/input.h | 1 + src/macro.c | 51 ++++++++++++++++++++++++++++++++----------------- src/mnemo.c | 8 ++++---- src/output.c | 5 ++++- src/version.h | 2 +- 10 files changed, 89 insertions(+), 48 deletions(-) diff --git a/docs/Errors.txt b/docs/Errors.txt index 0a6e0f7..20b94ff 100644 --- a/docs/Errors.txt +++ b/docs/Errors.txt @@ -303,9 +303,8 @@ Loop var must be followed by either "in" keyword or comma. Macro already defined. Macros can only be defined once. If you define a macro twice, ACME - will help you find the definitions by giving a warning for the - first definition and a serious error (stopping assembly) for the - second definition. + will help you find the definitions by giving a warning for the new + definition and then an error for the earlier definition. Macro not defined (or wrong signature). You tried to call a macro that either wasn't defined yet (always @@ -462,12 +461,6 @@ Loop count is negative. (getting this error is only possible when using the now deprecated syntax). -Macro already defined. - Macros can only be defined once. If you define a macro twice, ACME - will help you find both definitions by giving a warning for the - first definition and a serious error (stopping assembly) for the - second definition. - Missing '{'. ACME didn't find the expected '{' character. Remember that '{' characters must be given on the same line as the keyword they @@ -478,7 +471,7 @@ Out of memory. error. Free some memory and try again. It's highly unlikely anyone will ever see this error, though. ;) -Produced too much code. +Reached memory limit. The program counter reached address $10000, leaving the output buffer. At the moment, ACME can only produce a maximum of 64 KB. diff --git a/src/acme.c b/src/acme.c index 772b52f..a4ea217 100644 --- a/src/acme.c +++ b/src/acme.c @@ -310,6 +310,8 @@ static void perform_pass(void) int ii; ++pass.number; + if (config.process_verbosity > 1) + printf("Pass %d:\n", pass.number); cputype_passinit(); // set default cpu type output_passinit(); // set initial pc or start with undefined pc encoding_passinit(); // set default encoding @@ -347,10 +349,7 @@ static boolean do_actual_work(void) report = &global_report; // let global pointer point to something report_init(report); // we must init struct before doing passes - if (config.process_verbosity > 1) - puts("First pass."); pass.complain_about_undefined = FALSE; // disable until error pass needed - pass.number = -1; // pre-init, will be incremented by perform_pass() perform_pass(); // first pass // pretend there has been a previous pass, with one more undefined result undefs_before = pass.undefined_count + 1; @@ -358,8 +357,6 @@ static boolean do_actual_work(void) // stop on zero (FIXME - zero-check pass.needvalue_count instead!) while (pass.undefined_count && (pass.undefined_count < undefs_before)) { undefs_before = pass.undefined_count; - if (config.process_verbosity > 1) - puts("Further pass."); perform_pass(); if (--sanity.passes_left < 0) { // FIXME - exit with error @@ -384,7 +381,7 @@ static boolean do_actual_work(void) // There are still errors (unsolvable by doing further passes), // so perform additional pass to find and show them. if (config.process_verbosity > 1) - puts("Extra pass needed to find error."); + puts("Extra pass to display errors."); pass.complain_about_undefined = TRUE; // activate error output perform_pass(); // perform pass, but now show "value undefined" return FALSE; @@ -708,6 +705,8 @@ int main(int argc, const char *argv[]) if (argc == 1) show_help_and_exit(); cliargs_init(argc, argv); + // init var that may be needed for -DSYMBOL=VALUE + pass.number = PASS_NUMBER_EARLY; // init platform-specific stuff. // this may read the library path from an environment variable. PLATFORM_INIT; diff --git a/src/config.h b/src/config.h index f47897f..fefc14c 100644 --- a/src/config.h +++ b/src/config.h @@ -1,5 +1,5 @@ // ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code. -// Copyright (C) 1998-2020 Marco Baye +// Copyright (C) 1998-2024 Marco Baye // Have a look at "acme.c" for further info // // Configuration @@ -20,6 +20,15 @@ typedef unsigned int bits; typedef unsigned int scope_t; typedef signed long intval_t; // at least 32 bits typedef unsigned long uintval_t; // just for logical shift right + +// struct to remember where macros were defined (FIXME - use for symbols as well!) +struct location { + const char *filename; + int line_number; +}; + +// stuff for results from expression parser: + enum numtype { NUMTYPE_UNDEFINED, NUMTYPE_INT, diff --git a/src/global.c b/src/global.c index 502794c..ad740c4 100644 --- a/src/global.c +++ b/src/global.c @@ -513,6 +513,19 @@ void Throw_first_pass_warning(const char *message) } +// process error that might vanish if symbols change: +// if current pass is an "error output" pass, actually throw error. +// otherwise just set a flag to let mainloop know this pass wasn't successful. +void throw_symbol_error(const char *msg) +{ + // atm we just mimic the old behaviour. in future, do something like this: + //if (pass.is_error_pass) + Throw_error(msg); + //else + //pass.has_symbol_errors = TRUE; +} + + // handle bugs void BUG(const char *message, int code) { @@ -567,7 +580,7 @@ void output_object(struct object *object, struct iter_context *iter) void output_8(intval_t value) { if ((value < -0x80) || (value > 0xff)) - Throw_error(exception_number_out_of_8b_range); + throw_symbol_error(exception_number_out_of_8b_range); output_byte(value); } @@ -576,7 +589,7 @@ void output_8(intval_t value) void output_be16(intval_t value) { if ((value < -0x8000) || (value > 0xffff)) - Throw_error(exception_number_out_of_16b_range); + throw_symbol_error(exception_number_out_of_16b_range); output_byte(value >> 8); output_byte(value); } @@ -586,7 +599,7 @@ void output_be16(intval_t value) void output_le16(intval_t value) { if ((value < -0x8000) || (value > 0xffff)) - Throw_error(exception_number_out_of_16b_range); + throw_symbol_error(exception_number_out_of_16b_range); output_byte(value); output_byte(value >> 8); } @@ -596,7 +609,7 @@ void output_le16(intval_t value) void output_be24(intval_t value) { if ((value < -0x800000) || (value > 0xffffff)) - Throw_error(exception_number_out_of_24b_range); + throw_symbol_error(exception_number_out_of_24b_range); output_byte(value >> 16); output_byte(value >> 8); output_byte(value); @@ -607,7 +620,7 @@ void output_be24(intval_t value) void output_le24(intval_t value) { if ((value < -0x800000) || (value > 0xffffff)) - Throw_error(exception_number_out_of_24b_range); + throw_symbol_error(exception_number_out_of_24b_range); output_byte(value); output_byte(value >> 8); output_byte(value >> 16); @@ -624,7 +637,7 @@ void output_le24(intval_t value) void output_be32(intval_t value) { // if ((value < -0x80000000) || (value > 0xffffffff)) -// Throw_error(exception_number_out_of_32b_range); +// throw_symbol_error(exception_number_out_of_32b_range); output_byte(value >> 24); output_byte(value >> 16); output_byte(value >> 8); @@ -636,7 +649,7 @@ void output_be32(intval_t value) void output_le32(intval_t value) { // if ((value < -0x80000000) || (value > 0xffffffff)) -// Throw_error(exception_number_out_of_32b_range); +// throw_symbol_error(exception_number_out_of_32b_range); output_byte(value); output_byte(value >> 8); output_byte(value >> 16); diff --git a/src/global.h b/src/global.h index 73155e7..1020b39 100644 --- a/src/global.h +++ b/src/global.h @@ -117,7 +117,8 @@ struct pass { boolean complain_about_undefined; // will be FALSE until error pass is needed }; extern struct pass pass; -#define FIRST_PASS (pass.number == 0) +#define PASS_NUMBER_EARLY 0 // for symbol definitions on command line +#define FIRST_PASS (pass.number == 1) struct sanity { int macro_recursions_left; // for macro calls @@ -205,6 +206,11 @@ extern void Throw_first_pass_warning(const char *msg); // about more than one of his typos at a time. #define Throw_error(msg) throw_message(DEBUGLEVEL_ERROR, msg) +// process error that might vanish if symbols change: +// if current pass is an "error output" pass, actually throw error. +// otherwise just set a flag to let mainloop know this pass wasn't successful. +extern void throw_symbol_error(const char *msg); + // output a serious error (assembly stops, for example if outbuffer overruns). #define Throw_serious_error(msg) throw_message(DEBUGLEVEL_SERIOUS, msg) diff --git a/src/input.h b/src/input.h index b638eec..86f8eb3 100644 --- a/src/input.h +++ b/src/input.h @@ -31,6 +31,7 @@ enum inputsrc { INPUTSRC_RAM }; struct input { + // FIXME - use struct location for first two elements: const char *original_filename; // during RAM reads, too int line_number; // in file (on RAM reads, too) enum inputsrc source; diff --git a/src/macro.c b/src/macro.c index e977a71..5745a6e 100644 --- a/src/macro.c +++ b/src/macro.c @@ -28,11 +28,10 @@ static const char exception_macro_twice[] = "Macro already defined."; // macro struct type definition struct macro { - int def_line_number; // line number of definition for error msgs - char *def_filename, // file name of definition for error msgs - *original_name, // user-supplied name for error msgs - *parameter_list, // parameters (whole line) - *body; // RAM block containing macro body + struct location definition; // for "macro twice" error + char *original_name, // as section title in error msgs + *parameter_list, // parameters (whole line) + *body; // RAM block containing macro body }; // there's no need to make this a struct and add a type component: // when the macro has been found, accessing its parameter_list component @@ -98,6 +97,8 @@ static int pipe_comma(void) } // Return malloc'd copy of string +// (yes, we could also use strdup() from , but then we still would +// need to check for NULL etc.) static char *get_string_copy(const char *original) { size_t size; @@ -124,23 +125,39 @@ static int search_for_macro(struct rwnode **result, scope_t scope, int create) } // This function is called when an already existing macro is re-defined. -// It first outputs a warning and then a serious error, stopping assembly. +// It first outputs a warning and then an error. // Showing the first message as a warning guarantees that ACME does not reach // the maximum error limit inbetween. static void report_redefinition(struct rwnode *macro_node) { struct macro *original_macro = macro_node->body; + const char *buffered_filename; + int buffered_linenum; + const char *buffered_section_type; + char *buffered_section_title; // show warning with location of current definition Throw_warning(exception_macro_twice); // FIXME - throw as info? // CAUTION, ugly kluge: fiddle with input_now and section_now // data to generate helpful error messages - input_now->original_filename = original_macro->def_filename; - input_now->line_number = original_macro->def_line_number; - section_now->type = "original"; + // FIXME - move this to a function so "symbol twice" error can also use it + // buffer old data + buffered_filename = input_now->original_filename; + buffered_linenum = input_now->line_number; + buffered_section_type = section_now->type; + buffered_section_title = section_now->title; + // set new (fake) data + input_now->original_filename = original_macro->definition.filename; + input_now->line_number = original_macro->definition.line_number; + section_now->type = "earlier"; section_now->title = "definition"; - // show serious error with location of original definition - Throw_serious_error(exception_macro_twice); + // show error with location of earlier definition + Throw_error(exception_macro_twice); + // restore old data + input_now->original_filename = buffered_filename; + input_now->line_number = buffered_linenum; + section_now->type = buffered_section_type; + section_now->title = buffered_section_title; } // This function is only called during the first pass, so there's no need to @@ -194,11 +211,11 @@ void macro_parse_definition(void) // Now GotByte = illegal char after "!macro" // Search for macro. Create if not found. // But if found, complain (macro twice). if (search_for_macro(¯o_node, macro_scope, TRUE) == FALSE) - report_redefinition(macro_node); // quits with serious error + report_redefinition(macro_node); // Create new macro struct and set it up. Finally we'll read the body. new_macro = safe_malloc(sizeof(*new_macro)); - new_macro->def_line_number = input_now->line_number; - new_macro->def_filename = get_string_copy(input_now->original_filename); + new_macro->definition.line_number = input_now->line_number; + new_macro->definition.filename = get_string_copy(input_now->original_filename); new_macro->original_name = get_string_copy(user_macro_name->buffer); new_macro->parameter_list = formal_parameters; new_macro->body = input_skip_or_store_block(TRUE); // changes LineNumber @@ -275,8 +292,8 @@ void macro_parse_call(void) // Now GotByte = first char of macro name local_gotbyte = GotByte; // CAUTION - ugly kluge // set up new input - new_input.original_filename = actual_macro->def_filename; - new_input.line_number = actual_macro->def_line_number; + new_input.original_filename = actual_macro->definition.filename; + new_input.line_number = actual_macro->definition.line_number; new_input.source = INPUTSRC_RAM; new_input.state = INPUTSTATE_NORMAL; // FIXME - fix others! new_input.src.ram_ptr = actual_macro->parameter_list; @@ -324,7 +341,7 @@ void macro_parse_call(void) // Now GotByte = first char of macro name } // and now, finally, parse the actual macro body input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others! -// maybe call parse_ram_block(actual_macro->def_line_number, actual_macro->body) +// maybe call parse_ram_block(actual_macro->definition.line_number, actual_macro->body) input_now->src.ram_ptr = actual_macro->body; parse_until_eob_or_eof(); if (GotByte != CHAR_EOB) diff --git a/src/mnemo.c b/src/mnemo.c index 156aad3..fb9c823 100644 --- a/src/mnemo.c +++ b/src/mnemo.c @@ -749,7 +749,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi // Value is sure, so use its own size // if value is negative, size cannot be chosen. Complain! if (argument->val.intval < 0) { - Throw_error("Negative value - cannot choose addressing mode."); + throw_symbol_error("Negative value - cannot choose addressing mode."); return 0; } @@ -771,7 +771,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi } // Value is too big for all possible addressing modes - Throw_error(exception_number_out_of_range); + throw_symbol_error(exception_number_out_of_range); return 0; } @@ -793,7 +793,7 @@ static void not_in_bank(intval_t target) char buffer[60]; // 640K should be enough for anybody sprintf(buffer, "Target not in bank (0x%lx).", (long) target); - Throw_error(buffer); + throw_symbol_error(buffer); } // helper function for branches with 8-bit offset (including bbr0..7/bbs0..7) @@ -819,7 +819,7 @@ static void near_branch(int preoffset) char buffer[60]; // 640K should be enough for anybody sprintf(buffer, "Target out of range (%ld; %ld too far).", (long) offset, (long) (offset < -128 ? -128 - offset : offset - 127)); - Throw_error(buffer); + throw_symbol_error(buffer); } } } diff --git a/src/output.c b/src/output.c index 468645e..32c9777 100644 --- a/src/output.c +++ b/src/output.c @@ -87,8 +87,11 @@ static void find_segment_max(intval_t new_pc) // static void border_crossed(int current_offset) { + // FIXME - find a way to make this a normal error instead of a serious one, + // so it can be suppressed until we are sure the program won't shrink any + // further: if (current_offset >= config.outbuf_size) - Throw_serious_error("Produced too much code."); + Throw_serious_error("Reached memory limit."); // TODO - get rid of FIRST_PASS condition, because user can suppress these warnings if they want if (FIRST_PASS) { throw_message(config.debuglevel_segmentprobs, "Segment reached another one, overwriting it."); diff --git a/src/version.h b/src/version.h index d905435..8623b9f 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ #define RELEASE "0.97" // update before release FIXME #define CODENAME "Zem" // update before release -#define CHANGE_DATE "21 Feb" // update before release FIXME +#define CHANGE_DATE "22 Feb" // update before release FIXME #define CHANGE_YEAR "2024" // update before release //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME