refactored error/warning stuff

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@404 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-08-28 16:45:31 +00:00
parent ec4db48d07
commit be1b072288
19 changed files with 274 additions and 238 deletions

View File

@ -27,6 +27,7 @@
#define PLATFORM_SETFILETYPE_TEXT(a) #define PLATFORM_SETFILETYPE_TEXT(a)
// platform specific message output // platform specific message output
#define PLATFORM_INFO(a)
#define PLATFORM_WARNING(a) #define PLATFORM_WARNING(a)
#define PLATFORM_ERROR(a) #define PLATFORM_ERROR(a)
#define PLATFORM_SERIOUS(a) #define PLATFORM_SERIOUS(a)

View File

@ -27,6 +27,7 @@
#define PLATFORM_SETFILETYPE_TEXT(a) #define PLATFORM_SETFILETYPE_TEXT(a)
// platform specific message output // platform specific message output
#define PLATFORM_INFO(a)
#define PLATFORM_WARNING(a) #define PLATFORM_WARNING(a)
#define PLATFORM_ERROR(a) #define PLATFORM_ERROR(a)
#define PLATFORM_SERIOUS(a) #define PLATFORM_SERIOUS(a)

View File

@ -30,6 +30,7 @@
#define PLATFORM_SETFILETYPE_TEXT(a) RISCOS_set_filetype(a, 0xfff) #define PLATFORM_SETFILETYPE_TEXT(a) RISCOS_set_filetype(a, 0xfff)
// platform specific message output // platform specific message output
#define PLATFORM_INFO(a) RISCOS_throwback(a, 0)
#define PLATFORM_WARNING(a) RISCOS_throwback(a, 0) #define PLATFORM_WARNING(a) RISCOS_throwback(a, 0)
#define PLATFORM_ERROR(a) RISCOS_throwback(a, 1) #define PLATFORM_ERROR(a) RISCOS_throwback(a, 1)
#define PLATFORM_SERIOUS(a) RISCOS_throwback(a, 2) #define PLATFORM_SERIOUS(a) RISCOS_throwback(a, 2)

View File

@ -27,6 +27,7 @@
#define PLATFORM_SETFILETYPE_TEXT(a) #define PLATFORM_SETFILETYPE_TEXT(a)
// platform specific message output // platform specific message output
#define PLATFORM_INFO(a)
#define PLATFORM_WARNING(a) #define PLATFORM_WARNING(a)
#define PLATFORM_ERROR(a) #define PLATFORM_ERROR(a)
#define PLATFORM_SERIOUS(a) #define PLATFORM_SERIOUS(a)

View File

@ -333,6 +333,7 @@ static void save_output_file(void)
#define PF_COMPLAIN_ABOUT_UNDEFINEDS (1u << 0) // throw "Symbol not defined" errors #define PF_COMPLAIN_ABOUT_UNDEFINEDS (1u << 0) // throw "Symbol not defined" errors
#define PF_THROW_SEGMENT_MESSAGES (1u << 1) // throw segment warnings/errors #define PF_THROW_SEGMENT_MESSAGES (1u << 1) // throw segment warnings/errors
#define PF_GENERATE_OUTPUT (1u << 2) // generate output and/or report file #define PF_GENERATE_OUTPUT (1u << 2) // generate output and/or report file
#define PF_IS_FINAL_PASS (1u << 3) // mostly for special warnings
// perform a single pass // perform a single pass
static void perform_pass(bits passflags) static void perform_pass(bits passflags)
@ -347,6 +348,7 @@ static void perform_pass(bits passflags)
pass.counters.errors = 0; pass.counters.errors = 0;
pass.counters.warnings = 0; pass.counters.warnings = 0;
pass.flags.complain_about_undefined = !!(passflags & PF_COMPLAIN_ABOUT_UNDEFINEDS); pass.flags.complain_about_undefined = !!(passflags & PF_COMPLAIN_ABOUT_UNDEFINEDS);
pass.flags.is_final_pass = !!(passflags & PF_IS_FINAL_PASS);
pass.flags.throw_segment_messages = !!(passflags & PF_THROW_SEGMENT_MESSAGES); pass.flags.throw_segment_messages = !!(passflags & PF_THROW_SEGMENT_MESSAGES);
pass.flags.generate_output = !!(passflags & PF_GENERATE_OUTPUT); pass.flags.generate_output = !!(passflags & PF_GENERATE_OUTPUT);
@ -439,19 +441,19 @@ static void do_actual_work(void)
} }
} }
// last pass: // final pass:
// any errors left? // any errors left?
if (pass.counters.undefineds == 0) { // FIXME - use pass.counters.needvalue instead! if (pass.counters.undefineds == 0) { // FIXME - use pass.counters.needvalue instead!
// victory lap // victory lap
if (config.process_verbosity >= 2) if (config.process_verbosity >= 2)
puts("Extra pass to generate output."); puts("Extra pass to generate output.");
perform_pass(PF_GENERATE_OUTPUT); perform_pass(PF_IS_FINAL_PASS | PF_GENERATE_OUTPUT);
} else { } else {
// There are still errors (unsolvable by doing further passes), // There are still errors (unsolvable by doing further passes),
// so perform additional pass to find and show them. // so perform additional pass to find and show them.
if (config.process_verbosity >= 2) if (config.process_verbosity >= 2)
puts("Extra pass to display errors."); puts("Extra pass to display errors.");
perform_pass(PF_COMPLAIN_ABOUT_UNDEFINEDS); // perform pass, but now show "value undefined" perform_pass(PF_IS_FINAL_PASS | PF_COMPLAIN_ABOUT_UNDEFINEDS); // perform pass, but now show "value undefined"
// FIXME - perform_pass() calls exit() when there were errors, // FIXME - perform_pass() calls exit() when there were errors,
// so if controls returns here, call BUG()! // so if controls returns here, call BUG()!
// (this can be triggered using ifdef/ifndef) // (this can be triggered using ifdef/ifndef)

100
src/alu.c
View File

@ -250,7 +250,7 @@ static void enlarge_operator_stack(void)
//printf("Doubling op stack size to %d.\n", opstack_size); //printf("Doubling op stack size to %d.\n", opstack_size);
op_stack = realloc(op_stack, opstack_size * sizeof(*op_stack)); op_stack = realloc(op_stack, opstack_size * sizeof(*op_stack));
if (op_stack == NULL) if (op_stack == NULL)
Throw_serious_error(exception_no_memory_left); throw_serious_error(exception_no_memory_left);
} }
@ -261,7 +261,7 @@ static void enlarge_argument_stack(void)
//printf("Doubling arg stack size to %d.\n", argstack_size); //printf("Doubling arg stack size to %d.\n", argstack_size);
arg_stack = realloc(arg_stack, argstack_size * sizeof(*arg_stack)); arg_stack = realloc(arg_stack, argstack_size * sizeof(*arg_stack));
if (arg_stack == NULL) if (arg_stack == NULL)
Throw_serious_error(exception_no_memory_left); throw_serious_error(exception_no_memory_left);
} }
@ -332,7 +332,7 @@ static void is_not_defined(struct symbol *optional_symbol, char *name, size_t le
} }
dynabuf_add_string(errormsg_dyna_buf, ")."); dynabuf_add_string(errormsg_dyna_buf, ").");
dynabuf_append(errormsg_dyna_buf, '\0'); dynabuf_append(errormsg_dyna_buf, '\0');
Throw_error(errormsg_dyna_buf->buffer); throw_error(errormsg_dyna_buf->buffer);
} }
@ -367,7 +367,7 @@ static void get_symbol_value(scope_t scope, size_t name_length, unsigned int unp
if (arg->type == &type_number) { if (arg->type == &type_number) {
pseudopc_unpseudo(&arg->u.number, symbol->pseudopc, unpseudo_count); pseudopc_unpseudo(&arg->u.number, symbol->pseudopc, unpseudo_count);
} else { } else {
Throw_error("Un-pseudopc operator '&' can only be applied to number symbols."); throw_error("Un-pseudopc operator '&' can only be applied to number symbols.");
} }
} }
// if needed, output "value not defined" error // if needed, output "value not defined" error
@ -438,13 +438,13 @@ static void parse_quoted(char closing_quote)
// single character //////////////////////// // single character ////////////////////////
// too short? // too short?
if (GlobalDynaBuf->size == 0) { if (GlobalDynaBuf->size == 0) {
Throw_error(exception_missing_string); throw_error(exception_missing_string);
goto fail; goto fail;
} }
// too long? // too long?
if (GlobalDynaBuf->size != 1) if (GlobalDynaBuf->size != 1)
Throw_error("There's more than one character."); throw_error("There's more than one character.");
// parse character // parse character
value = encoding_encode_char(GLOBALDYNABUF_CURRENT[0]); value = encoding_encode_char(GLOBALDYNABUF_CURRENT[0]);
PUSH_INT_ARG(value, 0, 0); // no flags, no addr refs PUSH_INT_ARG(value, 0, 0); // no flags, no addr refs
@ -482,11 +482,10 @@ static void parse_binary_literal(void) // Now GotByte = "%" or "b"
break; // found illegal character break; // found illegal character
} }
if (!digits) { if (!digits) {
Throw_error("Binary literal without any digits."); throw_error("Binary literal without any digits.");
} }
if (digits & config.warn_bin_mask) { if (digits & config.warn_bin_mask) {
if (pass.number == 1) throw_finalpass_warning("Binary literal with strange number of digits.");
Throw_warning("Binary literal with strange number of digits.");
} }
// set force bits // set force bits
if (config.honor_leading_zeroes) { if (config.honor_leading_zeroes) {
@ -534,7 +533,7 @@ static void parse_hex_literal(void) // Now GotByte = "$" or "x"
break; // found illegal character break; // found illegal character
} }
if (!digits) if (!digits)
Throw_error("Hex literal without any digits."); throw_error("Hex literal without any digits.");
// set force bits // set force bits
if (config.honor_leading_zeroes) { if (config.honor_leading_zeroes) {
if (digits > 2) { if (digits > 2) {
@ -657,7 +656,7 @@ static void parse_function_call(void)
if (tree_easy_scan(function_tree, &node_body, function_dyna_buf)) { if (tree_easy_scan(function_tree, &node_body, function_dyna_buf)) {
PUSH_OP((struct op *) node_body); PUSH_OP((struct op *) node_body);
} else { } else {
Throw_error("Unknown function."); throw_error("Unknown function.");
alu_state = STATE_ERROR; alu_state = STATE_ERROR;
} }
} }
@ -732,7 +731,7 @@ static int parse_octal_or_unpseudo(void) // now GotByte = '&'
// // anonymous symbol // // anonymous symbol
// "unpseudo"-ing anonymous symbols is not supported // "unpseudo"-ing anonymous symbols is not supported
} else { } else {
Throw_error(exception_missing_string); // FIXME - create some "expected octal value or symbol name" error instead! throw_error(exception_missing_string); // FIXME - create some "expected octal value or symbol name" error instead!
return 1; // error return 1; // error
} }
return 0; // ok return 0; // ok
@ -784,7 +783,7 @@ static void handle_special_operator(struct expression *expression, enum op_id pr
alu_state = STATE_EXPECT_DYADIC_OP; alu_state = STATE_EXPECT_DYADIC_OP;
} else { } else {
// unmatched bracket // unmatched bracket
Throw_error("Unterminated list."); throw_error("Unterminated list.");
alu_state = STATE_ERROR; alu_state = STATE_ERROR;
// remove previous operator by overwriting with newest one... // remove previous operator by overwriting with newest one...
PREVIOUS_OPERATOR = NEWEST_OPERATOR; PREVIOUS_OPERATOR = NEWEST_OPERATOR;
@ -798,7 +797,7 @@ static void handle_special_operator(struct expression *expression, enum op_id pr
alu_state = STATE_EXPECT_DYADIC_OP; alu_state = STATE_EXPECT_DYADIC_OP;
} else { } else {
// unmatched bracket // unmatched bracket
Throw_error("Unterminated index spec."); throw_error("Unterminated index spec.");
alu_state = STATE_ERROR; alu_state = STATE_ERROR;
// remove previous operator by overwriting with newest one... // remove previous operator by overwriting with newest one...
PREVIOUS_OPERATOR = NEWEST_OPERATOR; PREVIOUS_OPERATOR = NEWEST_OPERATOR;
@ -1053,7 +1052,7 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
if (op_stack[op_sp - 1] == &ops_start_expression) { if (op_stack[op_sp - 1] == &ops_start_expression) {
push_dyadic_and_check(expression, &ops_terminating_char); push_dyadic_and_check(expression, &ops_terminating_char);
} else { } else {
Throw_error(exception_syntax); throw_error(exception_syntax);
alu_state = STATE_ERROR; alu_state = STATE_ERROR;
} }
return FALSE; // found delimiter return FALSE; // found delimiter
@ -1131,8 +1130,7 @@ static void expect_dyadic_operator(struct expression *expression)
if (GetByte() == '=') { if (GetByte() == '=') {
GetByte(); // eat second '=' character GetByte(); // eat second '=' character
} else { } else {
//if (pass.number == 1) //throw_finalpass_warning("old-style \"=\" comparison detected, please use \"==\" instead."); ACTIVATE!
// Throw_warning("old-style \"=\" comparison detected, please use \"==\" instead."); ACTIVATE!
} }
goto push_dyadic_op; goto push_dyadic_op;
@ -1211,7 +1209,7 @@ static void expect_dyadic_operator(struct expression *expression)
goto push_dyadic_op; goto push_dyadic_op;
} }
Throw_error("Unknown operator."); throw_error("Unknown operator.");
alu_state = STATE_ERROR; alu_state = STATE_ERROR;
//goto end; //goto end;
} else { } else {
@ -1252,7 +1250,7 @@ static void unsupported_operation(const struct object *optional, const struct op
dynabuf_add_string(errormsg_dyna_buf, arg->type->name); dynabuf_add_string(errormsg_dyna_buf, arg->type->name);
dynabuf_add_string(errormsg_dyna_buf, "\"."); dynabuf_add_string(errormsg_dyna_buf, "\".");
dynabuf_append(errormsg_dyna_buf, '\0'); dynabuf_append(errormsg_dyna_buf, '\0');
Throw_error(errormsg_dyna_buf->buffer); throw_error(errormsg_dyna_buf->buffer);
} }
@ -1430,7 +1428,7 @@ static void number_assign(struct object *self, const struct object *new_value, b
// symbol is already defined, so compare new and old values // symbol is already defined, so compare new and old values
// if values differ, complain and return // if values differ, complain and return
if (number_differs(self, new_value)) { if (number_differs(self, new_value)) {
Throw_error(exception_symbol_defined); throw_error(exception_symbol_defined);
return; return;
} }
// values are the same, so only fiddle with flags // values are the same, so only fiddle with flags
@ -1458,7 +1456,7 @@ static void number_assign(struct object *self, const struct object *new_value, b
static void list_assign(struct object *self, const struct object *new_value, boolean accept_change) static void list_assign(struct object *self, const struct object *new_value, boolean accept_change)
{ {
if ((!accept_change) && list_differs(self, new_value)) { if ((!accept_change) && list_differs(self, new_value)) {
Throw_error(exception_symbol_defined); throw_error(exception_symbol_defined);
return; return;
} }
*self = *new_value; *self = *new_value;
@ -1469,7 +1467,7 @@ static void list_assign(struct object *self, const struct object *new_value, boo
static void string_assign(struct object *self, const struct object *new_value, boolean accept_change) static void string_assign(struct object *self, const struct object *new_value, boolean accept_change)
{ {
if ((!accept_change) && string_differs(self, new_value)) { if ((!accept_change) && string_differs(self, new_value)) {
Throw_error(exception_symbol_defined); throw_error(exception_symbol_defined);
return; return;
} }
*self = *new_value; *self = *new_value;
@ -1581,7 +1579,7 @@ static void float_ranged_fn(double (*fn)(double), struct object *self)
if ((self->u.number.val.fpval >= -1) && (self->u.number.val.fpval <= 1)) { if ((self->u.number.val.fpval >= -1) && (self->u.number.val.fpval <= 1)) {
self->u.number.val.fpval = fn(self->u.number.val.fpval); self->u.number.val.fpval = fn(self->u.number.val.fpval);
} else { } else {
Throw_error("Argument out of range."); // TODO - add number output to error message throw_error("Argument out of range."); // TODO - add number output to error message
self->u.number.val.fpval = 0; self->u.number.val.fpval = 0;
} }
} }
@ -1796,8 +1794,7 @@ static void undef_handle_dyadic_operator(struct object *self, const struct op *o
goto shared; goto shared;
case OPID_EOR: case OPID_EOR:
if (pass.number == 1) throw_finalpass_warning("\"EOR\" is deprecated; use \"XOR\" instead."); // FIXME - change to error, at least for newest dialect!
Throw_warning("\"EOR\" is deprecated; use \"XOR\" instead.");
/*FALLTHROUGH*/ /*FALLTHROUGH*/
case OPID_XOR: case OPID_XOR:
case OPID_AND: case OPID_AND:
@ -1858,8 +1855,7 @@ static void int_handle_dyadic_operator(struct object *self, const struct op *op,
case OPID_EOR: case OPID_EOR:
case OPID_XOR: case OPID_XOR:
// convert other to int, warning user // convert other to int, warning user
if (pass.number == 1) throw_finalpass_warning(exception_float_to_int);
Throw_warning(exception_float_to_int); // FIXME - warning is never seen if arguments are undefined in first pass!
/*FALLTHROUGH*/ /*FALLTHROUGH*/
case OPID_MODULO: case OPID_MODULO:
case OPID_SHIFTLEFT: case OPID_SHIFTLEFT:
@ -1892,7 +1888,7 @@ static void int_handle_dyadic_operator(struct object *self, const struct op *op,
if (other->u.number.val.intval >= 0) { if (other->u.number.val.intval >= 0) {
self->u.number.val.intval = my_pow(self->u.number.val.intval, other->u.number.val.intval); self->u.number.val.intval = my_pow(self->u.number.val.intval, other->u.number.val.intval);
} else { } else {
Throw_error("Exponent is negative."); throw_error("Exponent is negative.");
self->u.number.val.intval = 0; self->u.number.val.intval = 0;
} }
break; break;
@ -1911,7 +1907,7 @@ static void int_handle_dyadic_operator(struct object *self, const struct op *op,
if (other->u.number.val.intval) { if (other->u.number.val.intval) {
self->u.number.val.intval %= other->u.number.val.intval; self->u.number.val.intval %= other->u.number.val.intval;
} else { } else {
Throw_error(exception_div_by_zero); throw_error(exception_div_by_zero);
self->u.number.val.intval = 0; self->u.number.val.intval = 0;
} }
break; break;
@ -1965,8 +1961,7 @@ static void int_handle_dyadic_operator(struct object *self, const struct op *op,
refs = self->u.number.addr_refs + other->u.number.addr_refs; // add address references refs = self->u.number.addr_refs + other->u.number.addr_refs; // add address references
break; break;
case OPID_EOR: case OPID_EOR:
if (pass.number == 1) throw_finalpass_warning("\"EOR\" is deprecated; use \"XOR\" instead."); // FIXME - change to error, at least for newest dialect!
Throw_warning("\"EOR\" is deprecated; use \"XOR\" instead.");
/*FALLTHROUGH*/ /*FALLTHROUGH*/
case OPID_XOR: case OPID_XOR:
self->u.number.val.intval ^= other->u.number.val.intval; self->u.number.val.intval ^= other->u.number.val.intval;
@ -2049,7 +2044,7 @@ static void float_handle_dyadic_operator(struct object *self, const struct op *o
if (other->u.number.val.fpval) { if (other->u.number.val.fpval) {
self->u.number.val.fpval /= other->u.number.val.fpval; self->u.number.val.fpval /= other->u.number.val.fpval;
} else { } else {
Throw_error(exception_div_by_zero); throw_error(exception_div_by_zero);
self->u.number.val.fpval = 0; self->u.number.val.fpval = 0;
} }
break; break;
@ -2057,7 +2052,7 @@ static void float_handle_dyadic_operator(struct object *self, const struct op *o
if (other->u.number.val.fpval) { if (other->u.number.val.fpval) {
self->u.number.val.intval = self->u.number.val.fpval / other->u.number.val.fpval; // fp becomes int! self->u.number.val.intval = self->u.number.val.fpval / other->u.number.val.fpval; // fp becomes int!
} else { } else {
Throw_error(exception_div_by_zero); throw_error(exception_div_by_zero);
self->u.number.val.intval = 0; self->u.number.val.intval = 0;
} }
self->u.number.ntype = NUMTYPE_INT; // result is int self->u.number.ntype = NUMTYPE_INT; // result is int
@ -2067,8 +2062,7 @@ static void float_handle_dyadic_operator(struct object *self, const struct op *o
case OPID_OR: case OPID_OR:
case OPID_EOR: case OPID_EOR:
case OPID_XOR: case OPID_XOR:
if (pass.number == 1) throw_finalpass_warning(exception_float_to_int);
Throw_warning(exception_float_to_int); // FIXME - warning is never seen if arguments are undefined in first pass!
/*FALLTHROUGH*/ /*FALLTHROUGH*/
case OPID_MODULO: case OPID_MODULO:
float_to_int(self); float_to_int(self);
@ -2163,7 +2157,7 @@ static int get_valid_index(int *target, int length, const struct object *self, c
return 1; return 1;
} }
if (other->u.number.ntype == NUMTYPE_UNDEFINED) { if (other->u.number.ntype == NUMTYPE_UNDEFINED) {
Throw_error("Index is undefined."); throw_error("Index is undefined.");
return 1; return 1;
} }
if (other->u.number.ntype == NUMTYPE_FLOAT) if (other->u.number.ntype == NUMTYPE_FLOAT)
@ -2176,7 +2170,7 @@ static int get_valid_index(int *target, int length, const struct object *self, c
if (index < 0) if (index < 0)
index += length; index += length;
if ((index < 0) || (index >= length)) { if ((index < 0) || (index >= length)) {
Throw_error("Index out of range."); throw_error("Index out of range.");
return 1; return 1;
} }
*target = index; *target = index;
@ -2550,9 +2544,9 @@ void ALU_any_int(intval_t *target) // ACCEPT_UNDEFINED
parse_expression(&expression); // FIXME - check return value and pass to caller! parse_expression(&expression); // FIXME - check return value and pass to caller!
if (expression.open_parentheses) if (expression.open_parentheses)
Throw_error(exception_paren_open); throw_error(exception_paren_open);
if (expression.is_empty) if (expression.is_empty)
Throw_error(exception_no_value); throw_error(exception_no_value);
if (expression.result.type == &type_number) { if (expression.result.type == &type_number) {
if (expression.result.u.number.ntype == NUMTYPE_UNDEFINED) if (expression.result.u.number.ntype == NUMTYPE_UNDEFINED)
*target = 0; *target = 0;
@ -2566,7 +2560,7 @@ void ALU_any_int(intval_t *target) // ACCEPT_UNDEFINED
// accept single-char strings, to be more // accept single-char strings, to be more
// compatible with versions before 0.97: // compatible with versions before 0.97:
if (expression.result.u.string->length != 1) { if (expression.result.u.string->length != 1) {
Throw_error(exception_lengthnot1); throw_error(exception_lengthnot1);
} else { } else {
// FIXME - throw a warning? // FIXME - throw a warning?
} }
@ -2574,7 +2568,7 @@ void ALU_any_int(intval_t *target) // ACCEPT_UNDEFINED
*target = expression.result.u.number.val.intval; *target = expression.result.u.number.val.intval;
} else { } else {
*target = 0; *target = 0;
Throw_error(exception_not_number); throw_error(exception_not_number);
} }
} }
@ -2604,12 +2598,12 @@ or
throws errors even though the result is defined! throws errors even though the result is defined!
*/ */
if (expression.open_parentheses) if (expression.open_parentheses)
Throw_error(exception_paren_open); throw_error(exception_paren_open);
if (expression.is_empty) if (expression.is_empty)
Throw_serious_error(exception_no_value); throw_serious_error(exception_no_value);
if (expression.result.type == &type_number) { if (expression.result.type == &type_number) {
if (expression.result.u.number.ntype == NUMTYPE_UNDEFINED) { if (expression.result.u.number.ntype == NUMTYPE_UNDEFINED) {
Throw_serious_error("Value not defined."); throw_serious_error("Value not defined.");
expression.result.u.number.val.intval = 0; expression.result.u.number.val.intval = 0;
} else if (expression.result.u.number.ntype == NUMTYPE_INT) { } else if (expression.result.u.number.ntype == NUMTYPE_INT) {
// ok // ok
@ -2622,13 +2616,13 @@ throws errors even though the result is defined!
// accept single-char strings, to be more // accept single-char strings, to be more
// compatible with versions before 0.97: // compatible with versions before 0.97:
if (expression.result.u.string->length != 1) { if (expression.result.u.string->length != 1) {
Throw_error(exception_lengthnot1); throw_error(exception_lengthnot1);
} else { } else {
// FIXME - throw a warning? // FIXME - throw a warning?
} }
string_to_byte(&(expression.result), 0); string_to_byte(&(expression.result), 0);
} else { } else {
Throw_serious_error(exception_not_number); throw_serious_error(exception_not_number);
} }
*intresult = expression.result.u.number; *intresult = expression.result.u.number;
} }
@ -2655,20 +2649,20 @@ void ALU_addrmode_int(struct expression *expression, int paren) // ACCEPT_UNDEFI
// accept single-char strings, to be more // accept single-char strings, to be more
// compatible with versions before 0.97: // compatible with versions before 0.97:
if (expression->result.u.string->length != 1) { if (expression->result.u.string->length != 1) {
Throw_error(exception_lengthnot1); throw_error(exception_lengthnot1);
} else { } else {
// FIXME - throw a warning? // FIXME - throw a warning?
} }
string_to_byte(&(expression->result), 0); string_to_byte(&(expression->result), 0);
} else { } else {
Throw_error(exception_not_number); throw_error(exception_not_number);
} }
if (expression->open_parentheses > paren) { if (expression->open_parentheses > paren) {
expression->open_parentheses = 0; expression->open_parentheses = 0;
Throw_error(exception_paren_open); throw_error(exception_paren_open);
} }
if (expression->is_empty) if (expression->is_empty)
Throw_error(exception_no_value); throw_error(exception_no_value);
} }
@ -2685,9 +2679,9 @@ void ALU_any_result(struct object *result) // ACCEPT_UNDEFINED | ACCEPT_FLOAT
parse_expression(&expression); // FIXME - check return value and pass to caller! parse_expression(&expression); // FIXME - check return value and pass to caller!
*result = expression.result; *result = expression.result;
if (expression.open_parentheses) if (expression.open_parentheses)
Throw_error(exception_paren_open); throw_error(exception_paren_open);
if (expression.is_empty) if (expression.is_empty)
Throw_error(exception_no_value); throw_error(exception_no_value);
} }
@ -2695,7 +2689,7 @@ void ALU_any_result(struct object *result) // ACCEPT_UNDEFINED | ACCEPT_FLOAT
maybe move maybe move
if (expression.is_empty) if (expression.is_empty)
Throw_error(exception_no_value); throw_error(exception_no_value);
to end of parse_expression() to end of parse_expression()

View File

@ -130,7 +130,7 @@ const struct cpu_type *cputype_find(void)
void vcpu_check_and_set_reg_length(boolean *var, boolean make_long) void vcpu_check_and_set_reg_length(boolean *var, boolean make_long)
{ {
if (((cpu_current_type->flags & CPUFLAG_SUPPORTSLONGREGS) == 0) && make_long) if (((cpu_current_type->flags & CPUFLAG_SUPPORTSLONGREGS) == 0) && make_long)
Throw_error("Chosen CPU does not support long registers."); throw_error("Chosen CPU does not support long registers.");
else else
*var = make_long; *var = make_long;
} }

View File

@ -38,7 +38,7 @@ static void resize(struct dynabuf *db, size_t new_size)
//printf("Growing dynabuf to size %d.\n", new_size); //printf("Growing dynabuf to size %d.\n", new_size);
new_buf = realloc(db->buffer, new_size); new_buf = realloc(db->buffer, new_size);
if (new_buf == NULL) if (new_buf == NULL)
Throw_serious_error(exception_no_memory_left); throw_serious_error(exception_no_memory_left);
db->reserved = new_size; db->reserved = new_size;
db->buffer = new_buf; db->buffer = new_buf;
} }

View File

@ -192,7 +192,7 @@ void flow_store_doloop_condition(struct condition *condition, char terminator)
} else if (strcmp(GlobalDynaBuf->buffer, "until") == 0) { } else if (strcmp(GlobalDynaBuf->buffer, "until") == 0) {
condition->invert = TRUE; condition->invert = TRUE;
} else { } else {
Throw_error("Expected WHILE or UNTIL keyword, or an empty loop condition."); throw_error("Expected WHILE or UNTIL keyword, or an empty loop condition.");
return; return;
} }
// write given condition into buffer // write given condition into buffer
@ -230,7 +230,7 @@ static boolean check_condition(struct condition *condition)
GetByte(); // proceed with next char GetByte(); // proceed with next char
ALU_defined_int(&intresult); ALU_defined_int(&intresult);
if (GotByte) if (GotByte)
Throw_serious_error("Unexpected char when evaluating loop condition."); // FIXME - include that char in the error message! throw_serious_error("Unexpected char when evaluating loop condition."); // FIXME - include that char in the error message!
return condition->invert ? !intresult.val.intval : !!intresult.val.intval; return condition->invert ? !intresult.val.intval : !!intresult.val.intval;
} }

View File

@ -143,7 +143,7 @@ void *safe_malloc(size_t size)
void *block = malloc(size); void *block = malloc(size);
if (block == NULL) if (block == NULL)
Throw_serious_error(exception_no_memory_left); throw_serious_error(exception_no_memory_left);
return block; return block;
} }
@ -197,7 +197,7 @@ extern void parser_set_nowarn_prefix(void)
static int first_symbol_of_statement(void) static int first_symbol_of_statement(void)
{ {
if (statement_flags & SF_FOUND_SYMBOL) { if (statement_flags & SF_FOUND_SYMBOL) {
Throw_error("Unknown mnemonic"); throw_error("Unknown mnemonic");
parser_skip_remainder(); parser_skip_remainder();
return FALSE; return FALSE;
} }
@ -216,8 +216,7 @@ static void set_label(scope_t scope, bits force_bit, bits powers)
struct object result; struct object result;
if ((statement_flags & SF_FOUND_BLANK) && config.warn_on_indented_labels) { if ((statement_flags & SF_FOUND_BLANK) && config.warn_on_indented_labels) {
if (pass.number == 1) throw_finalpass_warning("Label name not in leftmost column.");
Throw_warning("Label name not in leftmost column.");
} }
symbol = symbol_find(scope); symbol = symbol_find(scope);
result.type = &type_number; result.type = &type_number;
@ -288,8 +287,7 @@ static void parse_mnemo_or_global_symbol_def(void)
// 17 May 2014: now it works for UTF-8 as well. // 17 May 2014: now it works for UTF-8 as well.
if ((*GLOBALDYNABUF_CURRENT == (char) 0xa0) if ((*GLOBALDYNABUF_CURRENT == (char) 0xa0)
|| ((GlobalDynaBuf->size >= 2) && (GLOBALDYNABUF_CURRENT[0] == (char) 0xc2) && (GLOBALDYNABUF_CURRENT[1] == (char) 0xa0))) { || ((GlobalDynaBuf->size >= 2) && (GLOBALDYNABUF_CURRENT[0] == (char) 0xc2) && (GLOBALDYNABUF_CURRENT[1] == (char) 0xa0))) {
if (pass.number == 1) throw_finalpass_warning("Symbol name starts with a shift-space character.");
Throw_warning("Symbol name starts with a shift-space character.");
} }
parse_symbol_definition(SCOPE_GLOBAL); parse_symbol_definition(SCOPE_GLOBAL);
} }
@ -399,7 +397,7 @@ void parse_until_eob_or_eof(void)
if (BYTE_STARTS_KEYWORD(GotByte)) { if (BYTE_STARTS_KEYWORD(GotByte)) {
parse_mnemo_or_global_symbol_def(); parse_mnemo_or_global_symbol_def();
} else { } else {
Throw_error(exception_syntax); // FIXME - include char in error message! throw_error(exception_syntax); // FIXME - include char in error message!
parser_skip_remainder(); parser_skip_remainder();
} }
} }
@ -423,7 +421,7 @@ int parse_optional_block(void)
parse_until_eob_or_eof(); parse_until_eob_or_eof();
if (GotByte != CHAR_EOB) if (GotByte != CHAR_EOB)
Throw_serious_error(exception_no_right_brace); throw_serious_error(exception_no_right_brace);
GetByte(); GetByte();
return TRUE; return TRUE;
} }
@ -451,7 +449,7 @@ void parse_source_code_file(FILE *fd, const char *eternal_plat_filename)
// parse block and check end reason // parse block and check end reason
parse_until_eob_or_eof(); parse_until_eob_or_eof();
if (GotByte != CHAR_EOF) if (GotByte != CHAR_EOF)
Throw_error("Expected EOF, found '}' instead." ); throw_error("Expected EOF, found '}' instead." );
// restore outer input // restore outer input
inputchange_back(&icb); inputchange_back(&icb);
@ -476,7 +474,7 @@ bits parser_get_force_bit(void)
if (force_bit) if (force_bit)
GetByte(); GetByte();
else else
Throw_error("Illegal postfix."); throw_error("Illegal postfix.");
} }
SKIPSPACE(); SKIPSPACE();
return force_bit; return force_bit;
@ -489,7 +487,7 @@ bits parser_get_force_bit(void)
// errors. It shows the given message string, as well as the current // errors. It shows the given message string, as well as the current
// context: file name, line number, source type and source title. // context: file name, line number, source type and source title.
// if the "optional alternative location" given is NULL, the current location is used // if the "optional alternative location" given is NULL, the current location is used
static void throw_msg(const char *message, const char *ansicolor, const char *type, struct location *opt_alt_loc) static void print_msg(const char *message, const char *ansicolor, const char *type, struct location *opt_alt_loc)
{ {
const char *resetcolor = "\033[0m"; const char *resetcolor = "\033[0m";
struct location location; struct location location;
@ -531,14 +529,14 @@ void throw_message(enum debuglevel level, const char msg[], struct location *opt
// output a serious error // output a serious error
// (assembly stops, for example if outbuffer overruns). // (assembly stops, for example if outbuffer overruns).
PLATFORM_SERIOUS(msg); PLATFORM_SERIOUS(msg);
throw_msg(msg, "\033[1m\033[31m", "Serious error", opt_alt_loc); // bold + red print_msg(msg, "\033[1m\033[31m", "Serious error", opt_alt_loc); // bold + red
//++pass.counters.errors; // FIXME - needed when problem below is solved //++pass.counters.errors; // FIXME - needed when problem below is solved
exit(ACME_finalize(EXIT_FAILURE)); // FIXME - this inhibits output of macro call stack exit(ACME_finalize(EXIT_FAILURE)); // FIXME - this inhibits output of macro call stack
case DEBUGLEVEL_ERROR: case DEBUGLEVEL_ERROR:
// output an error // output an error
// (something is wrong, no output file will be generated). // (something is wrong, no output file will be generated).
PLATFORM_ERROR(msg); PLATFORM_ERROR(msg);
throw_msg(msg, "\033[31m", "Error", opt_alt_loc); // red print_msg(msg, "\033[31m", "Error", opt_alt_loc); // red
++pass.counters.errors; ++pass.counters.errors;
if (pass.counters.errors >= config.max_errors) if (pass.counters.errors >= config.max_errors)
exit(ACME_finalize(EXIT_FAILURE)); exit(ACME_finalize(EXIT_FAILURE));
@ -550,7 +548,7 @@ void throw_message(enum debuglevel level, const char msg[], struct location *opt
if (in_nowarn_block || (statement_flags & SF_NOWARN_PREFIX)) if (in_nowarn_block || (statement_flags & SF_NOWARN_PREFIX))
break; break;
PLATFORM_WARNING(msg); PLATFORM_WARNING(msg);
throw_msg(msg, "\033[33m", "Warning", opt_alt_loc); // yellow print_msg(msg, "\033[33m", "Warning", opt_alt_loc); // yellow
++pass.counters.warnings; ++pass.counters.warnings;
// then check if warnings should be handled like errors: // then check if warnings should be handled like errors:
if (config.all_warnings_are_errors) { if (config.all_warnings_are_errors) {
@ -560,15 +558,53 @@ void throw_message(enum debuglevel level, const char msg[], struct location *opt
} }
break; break;
case DEBUGLEVEL_INFO: case DEBUGLEVEL_INFO:
throw_msg(msg, "\033[32m", "Info", opt_alt_loc); // green PLATFORM_INFO(msg);
print_msg(msg, "\033[32m", "Info", opt_alt_loc); // green
break; break;
default: default:
// debug // debug
throw_msg(msg, "\033[36m", "Debug", opt_alt_loc); // cyan print_msg(msg, "\033[36m", "Debug", opt_alt_loc); // cyan
break; break;
} }
} }
// output a warning (something looks wrong)
void throw_warning(const char msg[])
{
throw_message(DEBUGLEVEL_WARNING, msg, NULL);
}
// output an error (something is wrong, no output file will be generated).
// the assembler will try to go on with the assembly, so the user gets to know
// about more than one of his typos at a time.
void throw_error(const char msg[])
{
throw_message(DEBUGLEVEL_ERROR, msg, NULL);
}
// output a serious error (assembly stops, for example if outbuffer overruns).
extern void throw_serious_error(const char msg[])
{
throw_message(DEBUGLEVEL_SERIOUS, msg, NULL);
}
// output a warning, but only if we are in first pass, otherwise suppress
// (only use this if using throw_finalpass_warning is impossible,
// for example in cases where the code is skipped in later passes)
void throw_pass1_warning(const char msg[])
{
if (pass.number == 1)
throw_warning(msg);
}
// output a warning, but only if we are in final pass, otherwise suppress
// (for example "converted float to int for XOR" -> must be done in
// final pass because values might be undefined earlier!)
void throw_finalpass_warning(const char msg[])
{
if (pass.flags.is_final_pass)
throw_warning(msg);
}
// throw "macro twice" error (FIXME - also use for "symbol twice"!) // throw "macro twice" error (FIXME - also use for "symbol twice"!)
// first output a warning, then an error, this guarantees that ACME does not // first output a warning, then an error, this guarantees that ACME does not
@ -592,30 +628,28 @@ void throw_redef_error(struct location *old_def, const char msg[])
section_now->type = buffered_section_type; section_now->type = buffered_section_type;
section_now->title = buffered_section_title; section_now->title = buffered_section_title;
// show error with location of current definition // show error with location of current definition
Throw_error(msg); throw_error(msg);
} }
// process error that might vanish if symbols change:
// if current pass is an "error output" pass, actually throw error.
// otherwise just increment counter 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.symbol_errors;
}
// handle bugs // handle bugs
// FIXME - use a local buffer and sprintf/snprintf to put error code into message! // FIXME - use a local buffer and sprintf/snprintf to put error code into message!
void BUG(const char *message, int code) void BUG(const char *message, int code)
{ {
Throw_warning("Bug in ACME, code follows"); throw_warning("Bug in ACME, code follows");
fprintf(stderr, "(0x%x:)", code); fprintf(stderr, "(0x%x:)", code);
Throw_serious_error(message); throw_serious_error(message);
}
// process error that might vanish if symbols change:
// if current pass is an "error output" pass, actually throw error.
// otherwise just increment counter to let mainloop know this pass wasn't successful.
void countorthrow_value_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.counters.suppressed_errors;
} }
@ -652,7 +686,7 @@ void output_object(struct object *object, struct iter_context *iter)
while (length--) while (length--)
iter->fn(iter->stringxor ^ encoding_encode_char(*(read++))); iter->fn(iter->stringxor ^ encoding_encode_char(*(read++)));
} else { } else {
Throw_error("There's more than one character."); // see alu.c for the original of this error throw_error("There's more than one character."); // see alu.c for the original of this error
} }
} else { } else {
BUG("IllegalObjectType", 0); BUG("IllegalObjectType", 0);
@ -664,7 +698,7 @@ void output_object(struct object *object, struct iter_context *iter)
void output_8(intval_t value) void output_8(intval_t value)
{ {
if ((value < -0x80) || (value > 0xff)) if ((value < -0x80) || (value > 0xff))
throw_symbol_error(exception_number_out_of_8b_range); countorthrow_value_error(exception_number_out_of_8b_range);
output_byte(value); output_byte(value);
} }
@ -673,7 +707,7 @@ void output_8(intval_t value)
void output_be16(intval_t value) void output_be16(intval_t value)
{ {
if ((value < -0x8000) || (value > 0xffff)) if ((value < -0x8000) || (value > 0xffff))
throw_symbol_error(exception_number_out_of_16b_range); countorthrow_value_error(exception_number_out_of_16b_range);
output_byte(value >> 8); output_byte(value >> 8);
output_byte(value); output_byte(value);
} }
@ -683,7 +717,7 @@ void output_be16(intval_t value)
void output_le16(intval_t value) void output_le16(intval_t value)
{ {
if ((value < -0x8000) || (value > 0xffff)) if ((value < -0x8000) || (value > 0xffff))
throw_symbol_error(exception_number_out_of_16b_range); countorthrow_value_error(exception_number_out_of_16b_range);
output_byte(value); output_byte(value);
output_byte(value >> 8); output_byte(value >> 8);
} }
@ -693,7 +727,7 @@ void output_le16(intval_t value)
void output_be24(intval_t value) void output_be24(intval_t value)
{ {
if ((value < -0x800000) || (value > 0xffffff)) if ((value < -0x800000) || (value > 0xffffff))
throw_symbol_error(exception_number_out_of_24b_range); countorthrow_value_error(exception_number_out_of_24b_range);
output_byte(value >> 16); output_byte(value >> 16);
output_byte(value >> 8); output_byte(value >> 8);
output_byte(value); output_byte(value);
@ -704,7 +738,7 @@ void output_be24(intval_t value)
void output_le24(intval_t value) void output_le24(intval_t value)
{ {
if ((value < -0x800000) || (value > 0xffffff)) if ((value < -0x800000) || (value > 0xffffff))
throw_symbol_error(exception_number_out_of_24b_range); countorthrow_value_error(exception_number_out_of_24b_range);
output_byte(value); output_byte(value);
output_byte(value >> 8); output_byte(value >> 8);
output_byte(value >> 16); output_byte(value >> 16);
@ -721,7 +755,7 @@ void output_le24(intval_t value)
void output_be32(intval_t value) void output_be32(intval_t value)
{ {
// if ((value < -0x80000000) || (value > 0xffffffff)) // if ((value < -0x80000000) || (value > 0xffffffff))
// throw_symbol_error(exception_number_out_of_32b_range); // countorthrow_value_error(exception_number_out_of_32b_range);
output_byte(value >> 24); output_byte(value >> 24);
output_byte(value >> 16); output_byte(value >> 16);
output_byte(value >> 8); output_byte(value >> 8);
@ -733,7 +767,7 @@ void output_be32(intval_t value)
void output_le32(intval_t value) void output_le32(intval_t value)
{ {
// if ((value < -0x80000000) || (value > 0xffffffff)) // if ((value < -0x80000000) || (value > 0xffffffff))
// throw_symbol_error(exception_number_out_of_32b_range); // countorthrow_value_error(exception_number_out_of_32b_range);
output_byte(value); output_byte(value);
output_byte(value >> 8); output_byte(value >> 8);
output_byte(value >> 16); output_byte(value >> 16);

View File

@ -110,15 +110,17 @@ struct pass {
int undefineds; // counts undefined expression results (if this stops decreasing, next pass must list them as errors) int undefineds; // counts undefined expression results (if this stops decreasing, next pass must list them as errors)
//int needvalue; // counts undefined expression results actually needed for output (when this hits zero, we're done) FIXME - use //int needvalue; // counts undefined expression results actually needed for output (when this hits zero, we're done) FIXME - use
int symbolchanges; // count symbol changes (if nonzero, another pass is needed) int symbolchanges; // count symbol changes (if nonzero, another pass is needed)
int errors; int errors; // if nonzero -> stop after this pass
int warnings; int warnings; // this is needed for showing macro call stack
// FIXME - add a counter for "errors not reported because pass flags //int suppressed_errors; // FIXME - this is for
// said so", because then we can read the value after all symbol changes // "errors not reported because pass flags said so", because
// have finally settled and know if the next pass is a victory lap or an // then we can read the value after all symbol changes have
// error output pass. // finally settled and know if the next pass is a victory lap or
// an error output pass.
} counters; } counters;
struct { struct {
boolean complain_about_undefined; // will be FALSE until error pass is needed boolean complain_about_undefined; // will be FALSE until error pass is needed
boolean is_final_pass; // needed for warnings like "converted float to int for xor"
boolean throw_segment_messages; // atm only used in pass 1, should be used in _last_ pass! boolean throw_segment_messages; // atm only used in pass 1, should be used in _last_ pass!
boolean generate_output; // create output and/or report file boolean generate_output; // create output and/or report file
} flags; } flags;
@ -211,29 +213,39 @@ extern bits parser_get_force_bit(void);
// if the "optional alternative location" given is NULL, the current location is used // if the "optional alternative location" given is NULL, the current location is used
extern void throw_message(enum debuglevel level, const char msg[], struct location *opt_alt_loc); extern void throw_message(enum debuglevel level, const char msg[], struct location *opt_alt_loc);
// output a warning (something looks wrong, like "label name starts with shift-space character") // output a warning (something looks wrong)
#define Throw_warning(msg) throw_message(DEBUGLEVEL_WARNING, msg, NULL) extern void throw_warning(const char msg[]);
// output an error (something is wrong, no output file will be generated). // output an error (something is wrong, no output file will be generated).
// the assembler will try to go on with the assembly, so the user gets to know // the assembler will try to go on with the assembly, so the user gets to know
// about more than one of his typos at a time. // about more than one of his typos at a time.
#define Throw_error(msg) throw_message(DEBUGLEVEL_ERROR, msg, NULL) extern void throw_error(const char msg[]);
// output a serious error (assembly stops, for example if outbuffer overruns).
extern void throw_serious_error(const char msg[]);
// output a warning, but only if we are in first pass, otherwise suppress
// (only use this if using throw_finalpass_warning is impossible,
// for example in cases where the code is skipped in later passes)
extern void throw_pass1_warning(const char msg[]);
// output a warning, but only if we are in final pass, otherwise suppress
// (for example "converted float to int for XOR" -> must be done in
// final pass because values might be undefined earlier!)
extern void throw_finalpass_warning(const char msg[]);
// throw "macro twice" error (FIXME - also use for "symbol twice"!) // throw "macro twice" error (FIXME - also use for "symbol twice"!)
// first output a warning, then an error, this guarantees that ACME does not // first output a warning, then an error, this guarantees that ACME does not
// reach the maximum error limit inbetween. // reach the maximum error limit inbetween.
extern void throw_redef_error(struct location *old_def, const char msg[]); extern void throw_redef_error(struct location *old_def, const char msg[]);
// handle bugs
extern void BUG(const char *msg, int code);
// process error that might vanish if symbols change: // process error that might vanish if symbols change:
// if current pass is an "error output" pass, actually throw error. // if current pass is an "error output" pass, actually throw error.
// otherwise just increment counter to let mainloop know this pass wasn't successful. // otherwise just increment counter to let mainloop know this pass wasn't successful.
extern void throw_symbol_error(const char *msg); extern void countorthrow_value_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, NULL)
// handle bugs
extern void BUG(const char *msg, int code);
// insert object (in case of list, will iterate/recurse until done) // insert object (in case of list, will iterate/recurse until done)
struct iter_context { struct iter_context {

View File

@ -253,7 +253,7 @@ static char get_processed_from_file(void)
default: default:
// complain if byte is 0 // complain if byte is 0
Throw_error("Source file contains illegal character."); // FIXME - throw some dynamic "did not expect XYZ character" error instead! throw_error("Source file contains illegal character."); // FIXME - throw some dynamic "did not expect XYZ character" error instead!
return (char) from_file; return (char) from_file;
} }
case INPUTSTATE_SKIPBLANKS: case INPUTSTATE_SKIPBLANKS:
@ -372,19 +372,19 @@ static void subst_substitute(void) // now GotByte = '?'
goto fail; // input_read_scope_and_symbol_name will have thrown error goto fail; // input_read_scope_and_symbol_name will have thrown error
} }
if (tmp_symbol->object.type == NULL) { if (tmp_symbol->object.type == NULL) {
Throw_error("Substitution symbol is undefined."); throw_error("Substitution symbol is undefined.");
// FIXME - set type to undefined int, just to make sure later refs via type do not crash! // FIXME - set type to undefined int, just to make sure later refs via type do not crash!
goto fail; goto fail;
} else if (tmp_symbol->object.type == &type_number) { } else if (tmp_symbol->object.type == &type_number) {
if (tmp_symbol->object.u.number.ntype != NUMTYPE_INT) { if (tmp_symbol->object.u.number.ntype != NUMTYPE_INT) {
Throw_error("Substitution symbol is undefined or not integer."); throw_error("Substitution symbol is undefined or not integer.");
goto fail; goto fail;
} }
dynabuf_add_signed_long(subst_buffer, (long) tmp_symbol->object.u.number.val.intval); dynabuf_add_signed_long(subst_buffer, (long) tmp_symbol->object.u.number.val.intval);
} else if (tmp_symbol->object.type == &type_string) { } else if (tmp_symbol->object.type == &type_string) {
dynabuf_add_bytes(subst_buffer, tmp_symbol->object.u.string->payload, tmp_symbol->object.u.string->length); dynabuf_add_bytes(subst_buffer, tmp_symbol->object.u.string->payload, tmp_symbol->object.u.string->length);
} else { } else {
Throw_error("Substitution symbol is neither number nor string."); throw_error("Substitution symbol is neither number nor string.");
goto fail; goto fail;
} }
@ -394,7 +394,7 @@ static void subst_substitute(void) // now GotByte = '?'
if (GotByte == ')') { if (GotByte == ')') {
GetByte(); // eat ')' GetByte(); // eat ')'
} else { } else {
Throw_error("Substitution does not end with ')' character."); throw_error("Substitution does not end with ')' character.");
goto fail; goto fail;
} }
} }
@ -522,7 +522,7 @@ static void get_quoted_byte(void)
} }
// now check for end of statement // now check for end of statement
if (GotByte == CHAR_EOS) if (GotByte == CHAR_EOS)
Throw_error("Quotes still open at end of line."); throw_error("Quotes still open at end of line.");
} }
// skip remainder of statement, for example on error // skip remainder of statement, for example on error
@ -555,7 +555,7 @@ void parser_ensure_EOS(void) // now GotByte = first char to test
// FIXME - change quoting: do not assume char is printable! // FIXME - change quoting: do not assume char is printable!
quote = (GotByte == '\'') ? '"' : '\''; // use single quotes, unless byte is a single quote (then use double quotes) quote = (GotByte == '\'') ? '"' : '\''; // use single quotes, unless byte is a single quote (then use double quotes)
sprintf(buf, "Expected end-of-statement, found %c%c%c instead.", quote, GotByte, quote); sprintf(buf, "Expected end-of-statement, found %c%c%c instead.", quote, GotByte, quote);
Throw_error(buf); throw_error(buf);
parser_skip_remainder(); parser_skip_remainder();
} }
} }
@ -628,7 +628,7 @@ int input_unescape_dynabuf(void)
break; break;
// TODO - 'a' to BEL? others? // TODO - 'a' to BEL? others?
default: default:
Throw_error("Unsupported backslash sequence."); // TODO - add unexpected character to error message? throw_error("Unsupported backslash sequence."); // TODO - add unexpected character to error message?
} }
GLOBALDYNABUF_CURRENT[write_index++] = byte; GLOBALDYNABUF_CURRENT[write_index++] = byte;
escaped = FALSE; escaped = FALSE;
@ -668,7 +668,7 @@ static void block_to_dynabuf(void)
// now check for some special characters // now check for some special characters
switch (byte) { switch (byte) {
case CHAR_EOF: // End-of-file in block? Sorry, no way. case CHAR_EOF: // End-of-file in block? Sorry, no way.
Throw_serious_error(exception_no_right_brace); throw_serious_error(exception_no_right_brace);
case '"': // Quotes? Okay, read quoted stuff. case '"': // Quotes? Okay, read quoted stuff.
case '\'': case '\'':
@ -725,7 +725,7 @@ static int append_keyword_to_global_dynabuf(void)
GetByte(); GetByte();
} }
if (length == 0) if (length == 0)
Throw_error(exception_missing_string); throw_error(exception_missing_string);
return length; return length;
} }
@ -741,7 +741,7 @@ int input_append_symbol_name_to_global_dynabuf(void)
GetByte(); GetByte();
} else if (!BYTE_STARTS_KEYWORD(GotByte)) { } else if (!BYTE_STARTS_KEYWORD(GotByte)) {
// FIXME - show invalid char in error message! // FIXME - show invalid char in error message!
Throw_error(exception_missing_string); throw_error(exception_missing_string);
return 1; // error return 1; // error
} }
return append_keyword_to_global_dynabuf() == 0; // zero length -> error! return append_keyword_to_global_dynabuf() == 0; // zero length -> error!
@ -822,7 +822,7 @@ static int read_filename_shared_end(boolean *absolute)
{ {
// check length // check length
if (GlobalDynaBuf->size == 0) { if (GlobalDynaBuf->size == 0) {
Throw_error("No file name given."); throw_error("No file name given.");
return 1; // error return 1; // error
} }
@ -871,7 +871,7 @@ int input_read_input_filename(struct filespecflags *flags)
flags->uses_lib = FALSE; flags->uses_lib = FALSE;
// old algo (do not merge with similar parts from "if" block!): // old algo (do not merge with similar parts from "if" block!):
if (GotByte != '"') { if (GotByte != '"') {
Throw_error("File name quotes not found (\"\" or <>)."); throw_error("File name quotes not found (\"\" or <>).");
return 1; // error return 1; // error
} }
// read file name string // read file name string
@ -913,7 +913,7 @@ int parser_expect(int chr)
GetByte(); // eat expected char GetByte(); // eat expected char
return TRUE; return TRUE;
} }
Throw_error(exception_syntax); // FIXME - build "expected X, found Y" error msg! throw_error(exception_syntax); // FIXME - build "expected X, found Y" error msg!
return FALSE; return FALSE;
} }
@ -943,7 +943,7 @@ static void library_path_to_pathbuf(void)
dynabuf_clear(pathbuf); dynabuf_clear(pathbuf);
lib_prefix = PLATFORM_LIBPREFIX; lib_prefix = PLATFORM_LIBPREFIX;
if ((PLATFORM_NEEDS_ENV_VAR) && (lib_prefix == NULL)) { if ((PLATFORM_NEEDS_ENV_VAR) && (lib_prefix == NULL)) {
Throw_error("\"ACME\" environment variable not found."); throw_error("\"ACME\" environment variable not found.");
} else { } else {
dynabuf_add_string(pathbuf, lib_prefix); dynabuf_add_string(pathbuf, lib_prefix);
} }
@ -995,11 +995,11 @@ int input_read_output_filename(void)
SKIPSPACE(); SKIPSPACE();
if (GotByte == '<') { if (GotByte == '<') {
Throw_error("Writing to library not supported."); throw_error("Writing to library not supported.");
return 1; // error return 1; // error
} }
if (GotByte != '"') { if (GotByte != '"') {
Throw_error("File name quotes not found (\"\")."); throw_error("File name quotes not found (\"\").");
return 1; // error return 1; // error
} }
dynabuf_clear(GlobalDynaBuf); dynabuf_clear(GlobalDynaBuf);
@ -1213,7 +1213,7 @@ FILE *includepaths_open_ro(struct filespecflags *flags)
dynabuf_append(pathbuf, flags->uses_lib ? '>' : '\"'); dynabuf_append(pathbuf, flags->uses_lib ? '>' : '\"');
dynabuf_append(pathbuf, '.'); dynabuf_append(pathbuf, '.');
dynabuf_append(pathbuf, '\0'); dynabuf_append(pathbuf, '\0');
Throw_error(pathbuf->buffer); throw_error(pathbuf->buffer);
} }
//fprintf(stderr, "File is [%s]\n", GLOBALDYNABUF_CURRENT); //fprintf(stderr, "File is [%s]\n", GLOBALDYNABUF_CURRENT);
return stream; return stream;

View File

@ -60,7 +60,7 @@ static void enlarge_arg_table(void)
//printf("Doubling arg table size to %d.\n", argtable_size); //printf("Doubling arg table size to %d.\n", argtable_size);
arg_table = realloc(arg_table, argtable_size * sizeof(*arg_table)); arg_table = realloc(arg_table, argtable_size * sizeof(*arg_table));
if (arg_table == NULL) if (arg_table == NULL)
Throw_serious_error(exception_no_memory_left); throw_serious_error(exception_no_memory_left);
} }
// Read macro scope and title. Title is read to GlobalDynaBuf and then copied // Read macro scope and title. Title is read to GlobalDynaBuf and then copied
@ -149,7 +149,7 @@ void macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
} while (pipe_comma()); } while (pipe_comma());
// ensure CHAR_SOB ('{') // ensure CHAR_SOB ('{')
if (GotByte != CHAR_SOB) if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace); throw_serious_error(exception_no_left_brace);
} }
dynabuf_append(GlobalDynaBuf, CHAR_EOS); // terminate param list dynabuf_append(GlobalDynaBuf, CHAR_EOS); // terminate param list
// now GlobalDynaBuf = comma-separated parameter list without spaces, // now GlobalDynaBuf = comma-separated parameter list without spaces,
@ -197,7 +197,7 @@ void macro_parse_call(void) // Now GotByte = first char of macro name
// Enter deeper nesting level // Enter deeper nesting level
// Quit program if recursion too deep. // Quit program if recursion too deep.
if (--sanity.macro_recursions_left < 0) if (--sanity.macro_recursions_left < 0)
Throw_serious_error("Too deeply nested. Recursive macro calls?"); throw_serious_error("Too deeply nested. Recursive macro calls?");
macro_scope = get_scope_and_title(); macro_scope = get_scope_and_title();
// now GotByte = first non-space after title // now GotByte = first non-space after title
// internal_name = MacroTitle ARG_SEPARATOR (grows to signature) // internal_name = MacroTitle ARG_SEPARATOR (grows to signature)
@ -234,7 +234,7 @@ void macro_parse_call(void) // Now GotByte = first char of macro name
// Search for macro. Do not create if not found. // Search for macro. Do not create if not found.
search_for_macro(&macro_node, macro_scope, FALSE); search_for_macro(&macro_node, macro_scope, FALSE);
if (macro_node == NULL) { if (macro_node == NULL) {
Throw_error("Macro not defined (or wrong signature)."); throw_error("Macro not defined (or wrong signature).");
parser_skip_remainder(); parser_skip_remainder();
} else { } else {
// make macro_node point to the macro struct // make macro_node point to the macro struct
@ -269,7 +269,7 @@ void macro_parse_call(void) // Now GotByte = first char of macro name
if (tree_hard_scan(&symbol_node, symbols_forest, symbol_scope, TRUE) == FALSE) { if (tree_hard_scan(&symbol_node, symbols_forest, symbol_scope, TRUE) == FALSE) {
// we expect it to exist in later passes, but in pass 1 it's an error: // we expect it to exist in later passes, but in pass 1 it's an error:
if (pass.number == 1) if (pass.number == 1)
Throw_error("Macro parameter twice."); throw_error("Macro parameter twice.");
} }
symbol_node->body = arg_table[arg_count].symbol; // CAUTION, object type may be NULL symbol_node->body = arg_table[arg_count].symbol; // CAUTION, object type may be NULL
} else { } else {
@ -301,7 +301,7 @@ void macro_parse_call(void) // Now GotByte = first char of macro name
// if needed, dump call stack // if needed, dump call stack
if (outer_msg_sum != pass.counters.warnings + pass.counters.errors) if (outer_msg_sum != pass.counters.warnings + pass.counters.errors)
Throw_warning("...called from here."); throw_warning("...called from here."); // FIXME - use DEBUGLEVEL_INFO instead!
parser_ensure_EOS(); parser_ensure_EOS();
} }

View File

@ -571,7 +571,7 @@ static int get_index(void)
NEXTANDSKIPSPACE(); NEXTANDSKIPSPACE();
return INDEX_Z; return INDEX_Z;
} }
Throw_error("Expected index register after comma."); throw_error("Expected index register after comma.");
return INDEX_NONE; return INDEX_NONE;
} }
@ -584,8 +584,7 @@ static void get_int_arg(struct number *result, boolean complain_about_indirect)
ALU_addrmode_int(&expression, 0); // accept 0 parentheses still open (-> complain!) ALU_addrmode_int(&expression, 0); // accept 0 parentheses still open (-> complain!)
if (expression.is_parenthesized && complain_about_indirect) { if (expression.is_parenthesized && complain_about_indirect) {
// TODO - raise error and be done with it? // TODO - raise error and be done with it?
if (pass.number == 1) throw_finalpass_warning("There are unneeded parentheses, you know indirect addressing is impossible here, right?"); // FIXME - rephrase? add to docs!
Throw_warning("There are unneeded parentheses, you know indirect addressing is impossible here, right?"); // FIXME - rephrase? add to docs!
} }
*result = expression.result.u.number; *result = expression.result.u.number;
} }
@ -652,11 +651,11 @@ static void check_oversize(bits size_bit, struct number *argument)
if (size_bit == NUMBER_FORCES_16) { if (size_bit == NUMBER_FORCES_16) {
// check 16-bit argument for high byte zero // check 16-bit argument for high byte zero
if ((argument->val.intval <= 255) && (argument->val.intval >= -128)) if ((argument->val.intval <= 255) && (argument->val.intval >= -128))
Throw_warning(exception_oversized_addrmode); throw_finalpass_warning(exception_oversized_addrmode);
} else { } else {
// check 24-bit argument for bank byte zero // check 24-bit argument for bank byte zero
if ((argument->val.intval <= 65535) && (argument->val.intval >= -32768)) if ((argument->val.intval <= 65535) && (argument->val.intval >= -32768))
Throw_warning(exception_oversized_addrmode); throw_finalpass_warning(exception_oversized_addrmode);
} }
} }
} }
@ -674,7 +673,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
{ {
// if there are no possible addressing modes, complain // if there are no possible addressing modes, complain
if (addressing_modes == MAYBE______) { if (addressing_modes == MAYBE______) {
Throw_error(exception_illegal_combination); throw_error(exception_illegal_combination);
return 0; return 0;
} }
// if a force bit postfix was given, act upon it // if a force bit postfix was given, act upon it
@ -684,7 +683,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
return force_bit; return force_bit;
// if not, complain // if not, complain
Throw_error("CPU does not support this postfix for this mnemonic."); throw_error("CPU does not support this postfix for this mnemonic.");
return 0; return 0;
} }
@ -701,7 +700,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
if (NUMBER_FORCES_24 & addressing_modes) if (NUMBER_FORCES_24 & addressing_modes)
return NUMBER_FORCES_24; return NUMBER_FORCES_24;
Throw_error(exception_number_out_of_range); // else error throw_error(exception_number_out_of_range); // else error
return 0; return 0;
} }
@ -744,7 +743,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
// Value is sure, so use its own size // Value is sure, so use its own size
// if value is negative, size cannot be chosen. Complain! // if value is negative, size cannot be chosen. Complain!
if (argument->val.intval < 0) { if (argument->val.intval < 0) {
throw_symbol_error("Negative value - cannot choose addressing mode."); countorthrow_value_error("Negative value - cannot choose addressing mode.");
return 0; return 0;
} }
@ -766,7 +765,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
} }
// Value is too big for all possible addressing modes // Value is too big for all possible addressing modes
throw_symbol_error(exception_number_out_of_range); countorthrow_value_error(exception_number_out_of_range);
return 0; return 0;
} }
@ -777,8 +776,7 @@ static void group_only_implied_addressing(int opcode)
// TODO - accept argument and complain about it? error message should tell more than "garbage data at end of line"! // TODO - accept argument and complain about it? error message should tell more than "garbage data at end of line"!
// for 65ce02 and 4502, warn about buggy decimal mode // for 65ce02 and 4502, warn about buggy decimal mode
if ((opcode == 0xf8) && (cpu_current_type->flags & CPUFLAG_DECIMALSUBTRACTBUGGY)) { if ((opcode == 0xf8) && (cpu_current_type->flags & CPUFLAG_DECIMALSUBTRACTBUGGY)) {
if (pass.number == 1) throw_finalpass_warning("Found SED instruction for CPU with known decimal SBC bug.");
Throw_warning("Found SED instruction for CPU with known decimal SBC bug.");
} }
output_byte(opcode); output_byte(opcode);
parser_ensure_EOS(); parser_ensure_EOS();
@ -790,7 +788,7 @@ static void not_in_bank(intval_t target)
char buffer[60]; // 640K should be enough for anybody char buffer[60]; // 640K should be enough for anybody
sprintf(buffer, "Target not in bank (0x%lx).", (long) target); sprintf(buffer, "Target not in bank (0x%lx).", (long) target);
throw_symbol_error(buffer); countorthrow_value_error(buffer);
} }
// helper function for branches with 8-bit offset (including bbr0..7/bbs0..7) // helper function for branches with 8-bit offset (including bbr0..7/bbs0..7)
@ -816,7 +814,7 @@ static void near_branch(int preoffset)
char buffer[60]; // 640K should be enough for anybody 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)); sprintf(buffer, "Target out of range (%ld; %ld too far).", (long) offset, (long) (offset < -128 ? -128 - offset : offset - 127));
throw_symbol_error(buffer); countorthrow_value_error(buffer);
} }
} }
} }
@ -917,7 +915,7 @@ static void check_zp_wraparound(struct number *result)
if ((result->ntype == NUMTYPE_INT) if ((result->ntype == NUMTYPE_INT)
&& (result->val.intval == 0xff) && (result->val.intval == 0xff)
&& (cpu_current_type->flags & CPUFLAG_WARN_ABOUT_FF_PTR)) && (cpu_current_type->flags & CPUFLAG_WARN_ABOUT_FF_PTR))
Throw_warning("Zeropage pointer wraps around from $ff to $00"); throw_finalpass_warning("Zeropage pointer wraps around from $ff to $00");
} }
// The main accumulator stuff (ADC, AND, CMP, EOR, LDA, ORA, SBC, STA) // The main accumulator stuff (ADC, AND, CMP, EOR, LDA, ORA, SBC, STA)
@ -981,7 +979,7 @@ static void group_main(int index, bits flags)
make_instruction(force_bit, &result, accu_lindz8[index]); make_instruction(force_bit, &result, accu_lindz8[index]);
break; break;
default: // other combinations are illegal default: // other combinations are illegal
Throw_error(exception_illegal_combination); throw_error(exception_illegal_combination);
} }
} }
@ -997,7 +995,7 @@ static void group_misc(int index, bits immediate_mode)
if (misc_impl[index]) if (misc_impl[index])
output_byte(misc_impl[index]); output_byte(misc_impl[index]);
else else
Throw_error(exception_illegal_combination); throw_error(exception_illegal_combination);
break; break;
case IMMEDIATE_ADDRESSING: // #$ff or #$ffff (depending on index register length) case IMMEDIATE_ADDRESSING: // #$ff or #$ffff (depending on index register length)
immediate_opcodes = imm_ops(&force_bit, misc_imm[index], immediate_mode); immediate_opcodes = imm_ops(&force_bit, misc_imm[index], immediate_mode);
@ -1009,9 +1007,9 @@ static void group_misc(int index, bits immediate_mode)
&& (result.ntype == NUMTYPE_INT) && (result.ntype == NUMTYPE_INT)
&& (result.val.intval != 0x00)) { && (result.val.intval != 0x00)) {
if (immediate_opcodes == 0x8b) if (immediate_opcodes == 0x8b)
Throw_warning("Assembling unstable ANE #NONZERO instruction"); throw_finalpass_warning("Assembling unstable ANE #NONZERO instruction");
else if (immediate_opcodes == 0xab) else if (immediate_opcodes == 0xab)
Throw_warning("Assembling unstable LXA #NONZERO instruction"); throw_finalpass_warning("Assembling unstable LXA #NONZERO instruction");
} }
break; break;
case ABSOLUTE_ADDRESSING: // $ff or $ffff case ABSOLUTE_ADDRESSING: // $ff or $ffff
@ -1024,7 +1022,7 @@ static void group_misc(int index, bits immediate_mode)
make_instruction(force_bit, &result, misc_yabs[index]); make_instruction(force_bit, &result, misc_yabs[index]);
break; break;
default: // other combinations are illegal default: // other combinations are illegal
Throw_error(exception_illegal_combination); throw_error(exception_illegal_combination);
} }
} }
@ -1096,7 +1094,7 @@ static void group_mvn_mvp(int opcode)
output_8(source.val.intval); output_8(source.val.intval);
// sanity check // sanity check
if (unmatched_hash) if (unmatched_hash)
Throw_error(exception_syntax); // FIXME - maybe "Use ARG,ARG or #ARG,#ARG but do not mix and match"? throw_error(exception_syntax); // FIXME - maybe "Use ARG,ARG or #ARG,#ARG but do not mix and match"?
parser_ensure_EOS(); parser_ensure_EOS();
} }
@ -1120,7 +1118,7 @@ static void group_prefix(int opcode)
char buffer[100]; // 640K should be enough for anybody char buffer[100]; // 640K should be enough for anybody
sprintf(buffer, "The chosen CPU uses opcode 0x%02x as a prefix code, do not use this mnemonic!", opcode); sprintf(buffer, "The chosen CPU uses opcode 0x%02x as a prefix code, do not use this mnemonic!", opcode);
Throw_error(buffer); throw_error(buffer);
} }
// The jump instructions. // The jump instructions.
@ -1139,7 +1137,7 @@ static void group_jump(int index)
if ((result.ntype == NUMTYPE_INT) if ((result.ntype == NUMTYPE_INT)
&& ((result.val.intval & 0xff) == 0xff) && ((result.val.intval & 0xff) == 0xff)
&& (cpu_current_type->flags & CPUFLAG_INDIRECTJMPBUGGY)) && (cpu_current_type->flags & CPUFLAG_INDIRECTJMPBUGGY))
Throw_warning("Assembling buggy JMP($xxff) instruction"); throw_finalpass_warning("Assembling buggy JMP($xxff) instruction");
break; break;
case X_INDEXED_INDIRECT_ADDRESSING: // ($ffff,x) case X_INDEXED_INDIRECT_ADDRESSING: // ($ffff,x)
make_instruction(force_bit, &result, jump_xind[index]); make_instruction(force_bit, &result, jump_xind[index]);
@ -1148,7 +1146,7 @@ static void group_jump(int index)
make_instruction(force_bit, &result, jump_lind[index]); make_instruction(force_bit, &result, jump_lind[index]);
break; break;
default: // other combinations are illegal default: // other combinations are illegal
Throw_error(exception_illegal_combination); throw_error(exception_illegal_combination);
} }
} }

View File

@ -105,7 +105,7 @@ static void border_crossed(int current_offset)
// so it can be suppressed until we are sure the program won't shrink any // so it can be suppressed until we are sure the program won't shrink any
// further: // further:
if (current_offset >= OUTBUF_MAXSIZE) if (current_offset >= OUTBUF_MAXSIZE)
Throw_serious_error("Reached memory limit."); throw_serious_error("Reached memory limit.");
if (pass.flags.throw_segment_messages) { if (pass.flags.throw_segment_messages) {
throw_message(config.debuglevel_segmentprobs, "Segment reached another one, overwriting it.", NULL); throw_message(config.debuglevel_segmentprobs, "Segment reached another one, overwriting it.", NULL);
find_segment_max(current_offset + 1); // find new (next) limit find_segment_max(current_offset + 1); // find new (next) limit
@ -148,7 +148,7 @@ static void real_output(intval_t byte)
// not happen again // not happen again
static void complain_and_use_dummy_pc(void) static void complain_and_use_dummy_pc(void)
{ {
Throw_error(exception_pc_undefined); throw_error(exception_pc_undefined);
programcounter_set(cpu_current_type->dummy_pc, 0); // 0 = no flags programcounter_set(cpu_current_type->dummy_pc, 0); // 0 = no flags
} }
@ -287,7 +287,7 @@ void output_passinit(void)
out->needed_bufsize = 16; // actually 1 would suffice... out->needed_bufsize = 16; // actually 1 would suffice...
} }
if (out->needed_bufsize > OUTBUF_MAXSIZE) { if (out->needed_bufsize > OUTBUF_MAXSIZE) {
Throw_serious_error("Output buffer size exceeds maximum."); throw_serious_error("Output buffer size exceeds maximum.");
} }
//fprintf(stderr, "Allocating outbuf of size 0x%06x.\n", out->needed_bufsize); //fprintf(stderr, "Allocating outbuf of size 0x%06x.\n", out->needed_bufsize);
out->buffer = safe_malloc(out->needed_bufsize); out->buffer = safe_malloc(out->needed_bufsize);
@ -404,9 +404,9 @@ static void start_segment(intval_t address_change, bits segment_flags)
// calculate start of new segment // calculate start of new segment
out->write_idx = out->write_idx + address_change; out->write_idx = out->write_idx + address_change;
if (out->write_idx < 0) { if (out->write_idx < 0) {
Throw_serious_error("Tried to write to negative addresses."); throw_serious_error("Tried to write to negative addresses.");
} else if (out->write_idx >= OUTBUF_MAXSIZE) { } else if (out->write_idx >= OUTBUF_MAXSIZE) {
Throw_serious_error("Reached memory limit."); throw_serious_error("Reached memory limit.");
} }
out->segm.start = out->write_idx; out->segm.start = out->write_idx;
out->segm.flags = segment_flags; out->segm.flags = segment_flags;
@ -556,11 +556,11 @@ int pseudopc_unpseudo(struct number *target, struct pseudopc *context, unsigned
return 0; // ok (no sense in trying to unpseudo this, and it might be an unresolved forward ref anyway) return 0; // ok (no sense in trying to unpseudo this, and it might be an unresolved forward ref anyway)
if (context == NULL) { if (context == NULL) {
Throw_error("Un-pseudopc operator '&' only works on addresses."); throw_error("Un-pseudopc operator '&' only works on addresses.");
return 1; // error return 1; // error
} }
if (context == &outermost_pseudopc_context) { if (context == &outermost_pseudopc_context) {
Throw_error("Un-pseudopc operator '&' has no !pseudopc context."); throw_error("Un-pseudopc operator '&' has no !pseudopc context.");
return 1; // error return 1; // error
} }
target->val.intval = target->val.intval - context->offset; // remove offset target->val.intval = target->val.intval - context->offset; // remove offset

View File

@ -57,7 +57,7 @@ static enum eos po_initmem(void)
// the "--initmem" cli arg and earlier calls have priority // the "--initmem" cli arg and earlier calls have priority
if (config.mem_init_value != NO_VALUE_GIVEN) { if (config.mem_init_value != NO_VALUE_GIVEN) {
Throw_warning("Memory already initialised."); throw_pass1_warning("Memory already initialised.");
return SKIP_REMAINDER; return SKIP_REMAINDER;
} }
@ -67,7 +67,7 @@ static enum eos po_initmem(void)
// first pass) // first pass)
ALU_defined_int(&intresult); ALU_defined_int(&intresult);
if ((intresult.val.intval > 255) || (intresult.val.intval < -128)) if ((intresult.val.intval > 255) || (intresult.val.intval < -128))
Throw_error(exception_number_out_of_8b_range); throw_error(exception_number_out_of_8b_range);
// remember value // remember value
config.mem_init_value = intresult.val.intval & 0xff; config.mem_init_value = intresult.val.intval & 0xff;
@ -86,7 +86,7 @@ static enum eos po_to(void)
// the "--outfile" cli arg and earlier calls have priority // the "--outfile" cli arg and earlier calls have priority
if (config.output_filename) { if (config.output_filename) {
Throw_warning("Output file name already chosen."); throw_pass1_warning("Output file name already chosen.");
return SKIP_REMAINDER; return SKIP_REMAINDER;
} }
@ -107,20 +107,20 @@ static enum eos po_to(void)
format = outputformat_find(); format = outputformat_find();
if (format == OUTFILE_FORMAT_UNSPECIFIED) { if (format == OUTFILE_FORMAT_UNSPECIFIED) {
Throw_error("Unknown output format."); throw_error("Unknown output format.");
return SKIP_REMAINDER; return SKIP_REMAINDER;
} }
} else { } else {
// no comma: complain unless user requested really old behaviour // no comma: complain unless user requested really old behaviour
if (config.dialect >= V0_86__DEPRECATE_REALPC) if (config.dialect >= V0_86__DEPRECATE_REALPC)
Throw_warning("Used \"!to\" without file format indicator."); throw_pass1_warning("Used \"!to\" without file format indicator.");
// default to cbm // default to cbm
format = OUTFILE_FORMAT_CBM; format = OUTFILE_FORMAT_CBM;
} }
// the "--format" cli arg has priority // the "--format" cli arg has priority
if (config.outfile_format != OUTFILE_FORMAT_UNSPECIFIED) { if (config.outfile_format != OUTFILE_FORMAT_UNSPECIFIED) {
Throw_warning("Output file format already chosen."); throw_pass1_warning("Output file format already chosen.");
} else { } else {
config.outfile_format = format; config.outfile_format = format;
} }
@ -137,7 +137,7 @@ static enum eos po_symbollist(void)
// cli arg and earlier calls have priority // cli arg and earlier calls have priority
if (config.symbollist_filename) { if (config.symbollist_filename) {
Throw_warning("Symbol list file name already chosen."); throw_pass1_warning("Symbol list file name already chosen.");
return SKIP_REMAINDER; return SKIP_REMAINDER;
} }
@ -163,8 +163,7 @@ static enum eos po_outfilestart(void)
if ((config.outfile_start != NO_VALUE_GIVEN) if ((config.outfile_start != NO_VALUE_GIVEN)
|| (last_pass_number == pass.number)) { || (last_pass_number == pass.number)) {
if (pass.number == 1) throw_pass1_warning("Start of output file already chosen.");
Throw_warning("Start of output file already chosen.");
} else { } else {
last_pass_number = pass.number; last_pass_number = pass.number;
outbuf_set_outfile_start(); outbuf_set_outfile_start();
@ -179,8 +178,7 @@ static enum eos po_outfilelimit(void)
if ((config.outfile_limit != NO_VALUE_GIVEN) if ((config.outfile_limit != NO_VALUE_GIVEN)
|| (last_pass_number == pass.number)) { || (last_pass_number == pass.number)) {
if (pass.number == 1) throw_pass1_warning("End of output file already chosen.");
Throw_warning("End of output file already chosen.");
} else { } else {
last_pass_number = pass.number; last_pass_number = pass.number;
outbuf_set_outfile_limit(); outbuf_set_outfile_limit();
@ -202,7 +200,7 @@ static enum eos po_xor(void)
old_value = output_get_xor(); old_value = output_get_xor();
ALU_any_int(&change); ALU_any_int(&change);
if ((change > 255) || (change < -128)) { if ((change > 255) || (change < -128)) {
Throw_error(exception_number_out_of_8b_range); throw_error(exception_number_out_of_8b_range);
change = 0; change = 0;
} }
output_set_xor(old_value ^ change); output_set_xor(old_value ^ change);
@ -321,7 +319,7 @@ static enum eos po_hex(void) // now GotByte = illegal char
// if we're here, the current character is not a hex digit, // if we're here, the current character is not a hex digit,
// which is only allowed outside of pairs: // which is only allowed outside of pairs:
if (digits == 1) { if (digits == 1) {
Throw_error("Hex digits are not given in pairs."); throw_error("Hex digits are not given in pairs.");
return SKIP_REMAINDER; // error exit return SKIP_REMAINDER; // error exit
} }
switch (GotByte) { switch (GotByte) {
@ -332,7 +330,7 @@ static enum eos po_hex(void) // now GotByte = illegal char
case CHAR_EOS: case CHAR_EOS:
return AT_EOS_ANYWAY; // normal exit return AT_EOS_ANYWAY; // normal exit
default: default:
Throw_error(exception_syntax); // FIXME - include character in error message! throw_error(exception_syntax); // FIXME - include character in error message!
return SKIP_REMAINDER; // error exit return SKIP_REMAINDER; // error exit
} }
} }
@ -343,11 +341,10 @@ static enum eos po_hex(void) // now GotByte = illegal char
static enum eos po_cbm(void) static enum eos po_cbm(void)
{ {
if (config.dialect >= V0_94_8__DISABLED_OBSOLETE) { if (config.dialect >= V0_94_8__DISABLED_OBSOLETE) {
Throw_error("\"!cbm\" is obsolete; use \"!ct pet\" instead."); throw_error("\"!cbm\" is obsolete; use \"!ct pet\" instead.");
} else { } else {
encoder_current = &encoder_pet; encoder_current = &encoder_pet;
if (pass.number == 1) throw_finalpass_warning("\"!cbm\" is deprecated; use \"!ct pet\" instead.");
Throw_warning("\"!cbm\" is deprecated; use \"!ct pet\" instead.");
} }
return ENSURE_EOS; return ENSURE_EOS;
} }
@ -371,7 +368,7 @@ static enum eos use_encoding_from_file(void)
if (stream) { if (stream) {
// try to load encoding table from given file // try to load encoding table from given file
if (fread(local_table, sizeof(char), 256, stream) != 256) if (fread(local_table, sizeof(char), 256, stream) != 256)
Throw_error("Conversion table incomplete."); throw_error("Conversion table incomplete.");
fclose(stream); fclose(stream);
} }
@ -445,7 +442,7 @@ static enum eos po_convtab(void)
return use_encoding_from_file(); return use_encoding_from_file();
} }
Throw_error("Unknown encoding."); throw_error("Unknown encoding.");
return use_predefined_encoding(encoder_current); // keep going return use_predefined_encoding(encoder_current); // keep going
} }
// insert string(s) // insert string(s)
@ -555,7 +552,7 @@ static enum eos po_binary(void)
// then parse it // then parse it
ALU_defined_int(&size); ALU_defined_int(&size);
if (size.val.intval < 0) if (size.val.intval < 0)
Throw_serious_error(exception_negative_size); throw_serious_error(exception_negative_size);
} }
// more? // more?
if (parser_accept_comma()) { if (parser_accept_comma()) {
@ -585,7 +582,7 @@ static enum eos po_binary(void)
} }
// if more should have been read, warn and add padding // if more should have been read, warn and add padding
if (size.val.intval > 0) { if (size.val.intval > 0) {
Throw_warning("Padding with zeroes."); throw_warning("Padding with zeroes.");
do { do {
output_byte(0); output_byte(0);
} while (--size.val.intval); } while (--size.val.intval);
@ -625,7 +622,7 @@ static enum eos po_skip(void) // now GotByte = illegal char
ALU_defined_int(&amount); // FIXME - forbid addresses! ALU_defined_int(&amount); // FIXME - forbid addresses!
if (amount.val.intval < 0) if (amount.val.intval < 0)
Throw_serious_error(exception_negative_size); // TODO - allow this? throw_serious_error(exception_negative_size); // TODO - allow this?
else else
output_skip(amount.val.intval); output_skip(amount.val.intval);
return ENSURE_EOS; return ENSURE_EOS;
@ -656,7 +653,7 @@ static enum eos po_align(void)
// make sure PC is defined // make sure PC is defined
programcounter_read(&pc); programcounter_read(&pc);
if (pc.ntype == NUMTYPE_UNDEFINED) { if (pc.ntype == NUMTYPE_UNDEFINED) {
Throw_error(exception_pc_undefined); throw_error(exception_pc_undefined);
return SKIP_REMAINDER; return SKIP_REMAINDER;
} }
@ -671,11 +668,10 @@ static void old_offset_assembly(void)
{ {
if (config.dialect >= V0_94_8__DISABLED_OBSOLETE) { if (config.dialect >= V0_94_8__DISABLED_OBSOLETE) {
// now it's obsolete // now it's obsolete
Throw_error("\"!pseudopc/!realpc\" are obsolete; use \"!pseudopc {}\" instead."); // FIXME - amend msg, tell user how to use old behaviour! throw_error("\"!pseudopc/!realpc\" are obsolete; use \"!pseudopc {}\" instead."); // FIXME - amend msg, tell user how to use old behaviour!
} else if (config.dialect >= V0_86__DEPRECATE_REALPC) { } else if (config.dialect >= V0_86__DEPRECATE_REALPC) {
// earlier it was deprecated // earlier it was deprecated
if (pass.number == 1) throw_finalpass_warning("\"!pseudopc/!realpc\" are deprecated; use \"!pseudopc {}\" instead.");
Throw_warning("\"!pseudopc/!realpc\" are deprecated; use \"!pseudopc {}\" instead.");
} else { } else {
// really old versions allowed it // really old versions allowed it
} }
@ -703,13 +699,13 @@ static enum eos po_pseudopc(void)
skip '=' skip '='
read segment name (quoted string!) read segment name (quoted string!)
} else { } else {
Throw_error("Unknown !pseudopc segment modifier."); throw_error("Unknown !pseudopc segment modifier.");
return SKIP_REMAINDER; return SKIP_REMAINDER;
} }
} }
*/ */
if (new_pc.val.intval < 0) { if (new_pc.val.intval < 0) {
Throw_error("Program counter cannot be negative."); throw_error("Program counter cannot be negative.");
new_pc.val.intval = cpu_current_type->dummy_pc; new_pc.val.intval = cpu_current_type->dummy_pc;
} }
pseudopc_start(&new_pc); pseudopc_start(&new_pc);
@ -756,7 +752,7 @@ static enum eos po_cpu(void)
if (new_cpu_type) if (new_cpu_type)
cpu_current_type = new_cpu_type; // activate new cpu type cpu_current_type = new_cpu_type; // activate new cpu type
else else
Throw_error("Unknown processor."); throw_error("Unknown processor.");
} }
// if there's a block, parse that and then restore old value // if there's a block, parse that and then restore old value
if (parse_optional_block()) if (parse_optional_block())
@ -808,7 +804,7 @@ static enum eos po_enum(void) // now GotByte = illegal char
step.val.intval = 1; step.val.intval = 1;
ALU_defined_int(&step); ALU_defined_int(&step);
Throw_serious_error("Not yet"); // FIXME throw_serious_error("Not yet"); // FIXME
return ENSURE_EOS; return ENSURE_EOS;
} }
#endif #endif
@ -879,10 +875,9 @@ static enum eos po_zone(void)
static enum eos po_subzone(void) static enum eos po_subzone(void)
{ {
if (config.dialect >= V0_94_8__DISABLED_OBSOLETE) { if (config.dialect >= V0_94_8__DISABLED_OBSOLETE) {
Throw_error("\"!subzone {}\" is obsolete; use \"!zone {}\" instead."); throw_error("\"!subzone {}\" is obsolete; use \"!zone {}\" instead.");
} else { } else {
if (pass.number == 1) throw_finalpass_warning("\"!subzone {}\" is deprecated; use \"!zone {}\" instead.");
Throw_warning("\"!subzone {}\" is deprecated; use \"!zone {}\" instead.");
} }
// call "!zone" instead // call "!zone" instead
return po_zone(); return po_zone();
@ -898,7 +893,7 @@ static enum eos po_source(void) // now GotByte = illegal char
// enter new nesting level // enter new nesting level
// quit program if recursion too deep // quit program if recursion too deep
if (--sanity.source_recursions_left < 0) if (--sanity.source_recursions_left < 0)
Throw_serious_error("Too deeply nested. Recursive \"!source\"?"); throw_serious_error("Too deeply nested. Recursive \"!source\"?");
// read file name and convert from UNIX style to platform style // read file name and convert from UNIX style to platform style
if (input_read_input_filename(&flags)) if (input_read_input_filename(&flags))
@ -937,7 +932,7 @@ static enum eos ifelse(enum ifmode mode)
ALU_defined_int(&ifresult); ALU_defined_int(&ifresult);
condition_met = !!ifresult.val.intval; condition_met = !!ifresult.val.intval;
if (GotByte != CHAR_SOB) if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace); throw_serious_error(exception_no_left_brace);
break; break;
case IFMODE_IFDEF: case IFMODE_IFDEF:
condition_met = check_ifdef_condition(); condition_met = check_ifdef_condition();
@ -960,7 +955,7 @@ static enum eos ifelse(enum ifmode mode)
parse_until_eob_or_eof(); // parse block parse_until_eob_or_eof(); // parse block
// if block isn't correctly terminated, complain and exit // if block isn't correctly terminated, complain and exit
if (GotByte != CHAR_EOB) if (GotByte != CHAR_EOB)
Throw_serious_error(exception_no_right_brace); throw_serious_error(exception_no_right_brace);
} else { } else {
return PARSE_REMAINDER; // parse line (only for ifdef/ifndef) return PARSE_REMAINDER; // parse line (only for ifdef/ifndef)
} }
@ -977,7 +972,7 @@ static enum eos ifelse(enum ifmode mode)
if (mode == IFMODE_ELSE) { if (mode == IFMODE_ELSE) {
// we could just return ENSURE_EOS, but checking here allows for better error message // we could just return ENSURE_EOS, but checking here allows for better error message
if (GotByte != CHAR_EOS) if (GotByte != CHAR_EOS)
Throw_error("Expected end-of-statement after ELSE block."); throw_error("Expected end-of-statement after ELSE block.");
return SKIP_REMAINDER; // normal exit after ELSE {...} return SKIP_REMAINDER; // normal exit after ELSE {...}
} }
@ -991,7 +986,7 @@ static enum eos ifelse(enum ifmode mode)
// make sure it's "else" // make sure it's "else"
if (strcmp(GlobalDynaBuf->buffer, "else")) { if (strcmp(GlobalDynaBuf->buffer, "else")) {
Throw_error("Expected end-of-statement or ELSE keyword after '}'."); throw_error("Expected end-of-statement or ELSE keyword after '}'.");
return SKIP_REMAINDER; // an error has been reported, so ignore rest of line return SKIP_REMAINDER; // an error has been reported, so ignore rest of line
} }
// anything more? // anything more?
@ -1014,7 +1009,7 @@ static enum eos ifelse(enum ifmode mode)
} else if (strcmp(GlobalDynaBuf->buffer, "ifndef") == 0) { } else if (strcmp(GlobalDynaBuf->buffer, "ifndef") == 0) {
mode = IFMODE_IFNDEF; mode = IFMODE_IFNDEF;
} else { } else {
Throw_error("Expected '{' or IF/IFDEF/IFNDEF keyword after ELSE keyword."); throw_error("Expected '{' or IF/IFDEF/IFNDEF keyword after ELSE keyword.");
return SKIP_REMAINDER; // an error has been reported, so ignore rest of line return SKIP_REMAINDER; // an error has been reported, so ignore rest of line
} }
} }
@ -1067,16 +1062,14 @@ static enum eos po_for(void) // now GotByte = illegal char
// new counter syntax // new counter syntax
loop.algorithm = FORALGO_NEWCOUNT; loop.algorithm = FORALGO_NEWCOUNT;
if (config.dialect < V0_94_12__NEW_FOR_SYNTAX) { if (config.dialect < V0_94_12__NEW_FOR_SYNTAX) {
if (pass.number == 1) throw_finalpass_warning("Found new \"!for\" syntax.");
Throw_warning("Found new \"!for\" syntax.");
} }
loop.u.counter.first = intresult.val.intval; // use first argument loop.u.counter.first = intresult.val.intval; // use first argument
ALU_defined_int(&intresult); // read second argument ALU_defined_int(&intresult); // read second argument
// compare addr_ref counts and complain if not equal! // compare addr_ref counts and complain if not equal!
if (config.warn_on_type_mismatch if (config.warn_on_type_mismatch
&& (intresult.addr_refs != loop.u.counter.addr_refs)) { && (intresult.addr_refs != loop.u.counter.addr_refs)) {
if (pass.number == 1) throw_finalpass_warning("Wrong type for loop's END value - must match type of START value.");
Throw_warning("Wrong type for loop's END value - must match type of START value.");
} }
// setup direction and total // setup direction and total
if (loop.u.counter.first <= intresult.val.intval) { if (loop.u.counter.first <= intresult.val.intval) {
@ -1092,11 +1085,10 @@ static enum eos po_for(void) // now GotByte = illegal char
// old counter syntax // old counter syntax
loop.algorithm = FORALGO_OLDCOUNT; loop.algorithm = FORALGO_OLDCOUNT;
if (config.dialect >= V0_94_12__NEW_FOR_SYNTAX) { if (config.dialect >= V0_94_12__NEW_FOR_SYNTAX) {
if (pass.number == 1) throw_finalpass_warning("Found old \"!for\" syntax.");
Throw_warning("Found old \"!for\" syntax.");
} }
if (intresult.val.intval < 0) { if (intresult.val.intval < 0) {
Throw_serious_error("Loop count is negative."); throw_serious_error("Loop count is negative.");
} }
// count up // count up
loop.u.counter.first = 1; loop.u.counter.first = 1;
@ -1108,11 +1100,11 @@ static enum eos po_for(void) // now GotByte = illegal char
loop.algorithm = FORALGO_ITERATE; loop.algorithm = FORALGO_ITERATE;
// check for "in" keyword // check for "in" keyword
if ((GotByte != 'i') && (GotByte != 'I')) { if ((GotByte != 'i') && (GotByte != 'I')) {
Throw_error(exception_want_IN_or_comma); throw_error(exception_want_IN_or_comma);
return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}' return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}'
} }
/* checking for the first character explicitly here looks dumb, but actually /* checking for the first character explicitly here looks dumb, but actually
solves a purpose: we're here because the check for comma failed, but maybe that serves a purpose: we're here because the check for comma failed, but maybe that
was just a typo. if the current byte is '.' or '-' or whatever, then trying to was just a typo. if the current byte is '.' or '-' or whatever, then trying to
read a keyword will result in "No string given" - which is confusing for the read a keyword will result in "No string given" - which is confusing for the
user if they did not even want to put a string there. user if they did not even want to put a string there.
@ -1121,23 +1113,23 @@ knowing there is an "i" also makes sure that parser_read_and_lower_keyword()
does not fail. */ does not fail. */
parser_read_and_lower_keyword(); parser_read_and_lower_keyword();
if (strcmp(GlobalDynaBuf->buffer, "in") != 0) { if (strcmp(GlobalDynaBuf->buffer, "in") != 0) {
Throw_error(exception_want_IN_or_comma); throw_error(exception_want_IN_or_comma);
return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}' return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}'
} }
if (force_bit) { if (force_bit) {
Throw_error("Force bits can only be given to counters, not when iterating over string/list contents."); throw_error("Force bits can only be given to counters, not when iterating over string/list contents.");
return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}' return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}'
} }
ALU_any_result(&loop.u.iter.obj); // get iterable ALU_any_result(&loop.u.iter.obj); // get iterable
loop.iterations_left = loop.u.iter.obj.type->length(&loop.u.iter.obj); loop.iterations_left = loop.u.iter.obj.type->length(&loop.u.iter.obj);
if (loop.iterations_left < 0) { if (loop.iterations_left < 0) {
Throw_error("Given object is not iterable."); throw_error("Given object is not iterable.");
return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}' return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}'
} }
} }
if (GotByte != CHAR_SOB) if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace); throw_serious_error(exception_no_left_brace);
input_block_getcopy(&loop.block); // "body" must be freed afterward... input_block_getcopy(&loop.block); // "body" must be freed afterward...
flow_forloop(&loop); flow_forloop(&loop);
@ -1158,7 +1150,7 @@ static enum eos po_do(void) // now GotByte = illegal char
SKIPSPACE(); SKIPSPACE();
flow_store_doloop_condition(&loop.head_cond, CHAR_SOB); // must be freed! flow_store_doloop_condition(&loop.head_cond, CHAR_SOB); // must be freed!
if (GotByte != CHAR_SOB) if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace); throw_serious_error(exception_no_left_brace);
input_block_getcopy(&loop.block); // "body" must be freed! input_block_getcopy(&loop.block); // "body" must be freed!
// now GotByte = '}' // now GotByte = '}'
@ -1184,7 +1176,7 @@ static enum eos po_while(void) // now GotByte = illegal char
SKIPSPACE(); SKIPSPACE();
flow_store_while_condition(&loop.head_cond); // "body" must be freed! flow_store_while_condition(&loop.head_cond); // "body" must be freed!
if (GotByte != CHAR_SOB) if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace); throw_serious_error(exception_no_left_brace);
// read block // read block
input_block_getcopy(&loop.block); // "body" must be freed! input_block_getcopy(&loop.block); // "body" must be freed!
// clear tail condition // clear tail condition
@ -1245,7 +1237,7 @@ static enum eos tracewatch(boolean enter_monitor)
} else if (strcmp(GlobalDynaBuf->buffer, "exec") == 0) { } else if (strcmp(GlobalDynaBuf->buffer, "exec") == 0) {
flags |= TRACEWATCH_EXEC; flags |= TRACEWATCH_EXEC;
} else { } else {
Throw_error("Unknown flag (known are: load, store, exec)."); // FIXME - add to docs! throw_error("Unknown flag (known are: load, store, exec)."); // FIXME - add to docs!
return SKIP_REMAINDER; return SKIP_REMAINDER;
} }
} while (parser_accept_comma()); } while (parser_accept_comma());
@ -1501,7 +1493,7 @@ void pseudoopcode_parse(void) // now GotByte = '!' (or '.' in case of --fullstop
// call function // call function
then = fn(); then = fn();
} else { } else {
Throw_error("Unknown pseudo opcode."); throw_error("Unknown pseudo opcode.");
} }
} }
if (then == SKIP_REMAINDER) if (then == SKIP_REMAINDER)
@ -1550,7 +1542,7 @@ void notreallypo_setpc(void) // GotByte is '*'
skip '=' skip '='
read segment name (quoted string!) */ read segment name (quoted string!) */
} else { } else {
Throw_error("Unknown \"*=\" segment modifier."); throw_error("Unknown \"*=\" segment modifier.");
goto fail; goto fail;
} }
} }
@ -1562,7 +1554,7 @@ void notreallypo_setpc(void) // GotByte is '*'
// current behaviour: // current behaviour:
// setting pc does not disable pseudopc // setting pc does not disable pseudopc
} else if (config.dialect >= V0_93__SHORTER_SETPC_WARNING) { } else if (config.dialect >= V0_93__SHORTER_SETPC_WARNING) {
Throw_warning("Offset assembly still active at end of segment."); throw_warning("Offset assembly still active at end of segment.");
end_all_pseudopc(); // warning did not say it would end_all_pseudopc(); // warning did not say it would
// disable pseudopc, but still did. nevertheless, there // disable pseudopc, but still did. nevertheless, there
// is something different to older versions: when the // is something different to older versions: when the
@ -1570,13 +1562,13 @@ void notreallypo_setpc(void) // GotByte is '*'
// stuff happens! i see no reason to try to mimic that. // stuff happens! i see no reason to try to mimic that.
} else { } else {
// prior to 0.93, setting pc disabled pseudopc with a warning: // prior to 0.93, setting pc disabled pseudopc with a warning:
Throw_warning("Offset assembly still active at end of segment. Switched it off."); throw_warning("Offset assembly still active at end of segment. Switched it off.");
end_all_pseudopc(); end_all_pseudopc();
} }
} }
if (intresult.val.intval < 0) { if (intresult.val.intval < 0) {
Throw_error("Program counter cannot be negative."); throw_error("Program counter cannot be negative.");
intresult.val.intval = cpu_current_type->dummy_pc; intresult.val.intval = cpu_current_type->dummy_pc;
} }
programcounter_set(intresult.val.intval, segment_flags); programcounter_set(intresult.val.intval, segment_flags);

View File

@ -154,7 +154,7 @@ void symbol_set_object(struct symbol *symbol, struct object *new_value, bits pow
// if too different, needs power (or complains) // if too different, needs power (or complains)
if (symbol->object.type != new_value->type) { if (symbol->object.type != new_value->type) {
if (!(powers & POWER_CHANGE_OBJTYPE)) if (!(powers & POWER_CHANGE_OBJTYPE))
Throw_error(exception_symbol_defined); throw_error(exception_symbol_defined);
// CAUTION: if above line throws error, we still go ahead and change type! // CAUTION: if above line throws error, we still go ahead and change type!
// this is to keep "!for" working, where the counter var is accessed. // this is to keep "!for" working, where the counter var is accessed.
symbol->object = *new_value; // copy whole struct including type symbol->object = *new_value; // copy whole struct including type
@ -182,7 +182,7 @@ void symbol_set_force_bit(struct symbol *symbol, bits force_bit)
BUG("NullTypeObject", 0); BUG("NullTypeObject", 0);
if (symbol->object.type != &type_number) { if (symbol->object.type != &type_number) {
Throw_error("Force bits can only be given to numbers."); throw_error("Force bits can only be given to numbers.");
return; return;
} }
@ -195,7 +195,7 @@ void symbol_set_force_bit(struct symbol *symbol, bits force_bit)
// it's too late to change, so check if the wanted bit is actually different // it's too late to change, so check if the wanted bit is actually different
if ((symbol->object.u.number.flags & NUMBER_FORCEBITS) != force_bit) if ((symbol->object.u.number.flags & NUMBER_FORCEBITS) != force_bit)
Throw_error("Too late for postfix."); throw_error("Too late for postfix.");
} }

View File

@ -19,7 +19,7 @@ void typesystem_want_nonaddr(struct number *result)
return; return;
if (result->addr_refs != 0) { if (result->addr_refs != 0) {
Throw_warning("Wrong type - expected integer."); throw_finalpass_warning("Wrong type - expected integer.");
//printf("refcount should be 0, but is %d\n", result->addr_refs); //printf("refcount should be 0, but is %d\n", result->addr_refs);
} }
} }
@ -34,7 +34,7 @@ void typesystem_want_addr(struct number *result)
return; return;
if (result->addr_refs != 1) { if (result->addr_refs != 1) {
Throw_warning("Wrong type - expected address."); throw_finalpass_warning("Wrong type - expected address.");
//printf("refcount should be 1, but is %d\n", result->addr_refs); //printf("refcount should be 1, but is %d\n", result->addr_refs);
} }
} }

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME #define RELEASE "0.97" // update before release FIXME
#define CODENAME "Zem" // update before release #define CODENAME "Zem" // update before release
#define CHANGE_DATE "6 Aug" // update before release FIXME #define CHANGE_DATE "7 Aug" // update before release FIXME
#define CHANGE_YEAR "2024" // update before release #define CHANGE_YEAR "2024" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME