mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-11-25 23:49:25 +00:00
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:
parent
ec4db48d07
commit
be1b072288
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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
100
src/alu.c
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
116
src/global.c
116
src/global.c
@ -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);
|
||||||
|
44
src/global.h
44
src/global.h
@ -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 {
|
||||||
|
36
src/input.c
36
src/input.c
@ -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;
|
||||||
|
12
src/macro.c
12
src/macro.c
@ -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(¯o_node, macro_scope, FALSE);
|
search_for_macro(¯o_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();
|
||||||
}
|
}
|
||||||
|
46
src/mnemo.c
46
src/mnemo.c
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
src/output.c
14
src/output.c
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user