another one of those "great rename" cleanup commits, no change in functionality

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@331 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-02-08 19:17:07 +00:00
parent e90cfc90b2
commit 2092961bb8
25 changed files with 464 additions and 398 deletions

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Platform specific stuff (in this case, for RISC OS)
@ -90,14 +90,14 @@ void RISCOS_throwback(const char *message, int type)
regs.r[0] = 0;
regs.r[1] = 0;
// regs.r[2] = (int) toplevel_source;
regs.r[2] = (int) Input_now->original_filename;
regs.r[2] = (int) input_now->original_filename;
_kernel_swi(XDDEUTILS_THROWBACKSEND, &regs, &regs);
}
// send throwback message
regs.r[0] = 1;
regs.r[1] = 0;
regs.r[2] = (int) Input_now->original_filename;
regs.r[3] = Input_now->line_number;
regs.r[2] = (int) input_now->original_filename;
regs.r[3] = input_now->line_number;
regs.r[4] = type;
regs.r[5] = (int) message;
_kernel_swi(XDDEUTILS_THROWBACKSEND, &regs, &regs);

View File

@ -236,7 +236,7 @@ static void save_output_file(void)
output_filename);
return;
}
Output_save_file(fd);
output_save_file(fd);
fclose(fd);
}
@ -249,7 +249,7 @@ static void perform_pass(void)
++pass.number;
// call modules' "pass init" functions
Output_passinit(); // disable output, PC undefined
output_passinit(); // disable output, PC undefined
cputype_passinit(default_cpu); // set default cpu type
// if start address was given on command line, use it:
if (start_address != ILLEGAL_START_ADDRESS)
@ -271,7 +271,7 @@ static void perform_pass(void)
++pass.error_count;
}
}
Output_end_segment();
output_end_segment();
/* TODO:
if --save-start is given, parse arg string
if --save-limit is given, parse arg string
@ -648,7 +648,7 @@ int main(int argc, const char *argv[])
// generate list of files to process
cliargs_get_rest(&toplevel_src_count, &toplevel_sources, "No top level sources given");
// init output buffer
Output_init(fill_value, config.test_new_features);
output_createbuffer(fill_value, /* use_large_buf= */ config.test_new_features);
if (do_actual_work())
save_output_file();
return ACME_finalize(EXIT_SUCCESS); // dump labels, if wanted

View File

@ -326,7 +326,7 @@ static void is_not_defined(struct symbol *optional_symbol, char *name, size_t le
dynabuf_add_string(errormsg_dyna_buf, name);
if (errormsg_dyna_buf->size < length) {
Bug_found("IllegalSymbolNameLength", errormsg_dyna_buf->size - length);
BUG("IllegalSymbolNameLength", errormsg_dyna_buf->size - length);
} else {
errormsg_dyna_buf->size = length;
}
@ -357,7 +357,7 @@ static void get_symbol_value(scope_t scope, size_t name_length, unsigned int unp
symbol->object.u.number.flags = NUMBER_EVER_UNDEFINED; // reading undefined taints it
symbol->object.u.number.addr_refs = 0;
} else {
// FIXME - add sanity check for UNDEFINED where EVER_UNDEFINED is false -> Bug_found()!
// FIXME - add sanity check for UNDEFINED where EVER_UNDEFINED is false -> BUG()!
// (because the only way to have UNDEFINED is the block above, and EVER_UNDEFINED taints everything it touches)
}
// first push on arg stack, so we have a local copy we can "unpseudo"
@ -413,13 +413,13 @@ static void parse_quoted(char closing_quote)
intval_t value;
dynabuf_clear(GlobalDynaBuf);
if (Input_quoted_to_dynabuf(closing_quote))
if (input_quoted_to_dynabuf(closing_quote))
goto fail; // unterminated or escaping error
// eat closing quote
GetByte();
// now convert to unescaped version
if (Input_unescape_dynabuf(0))
if (input_unescape_dynabuf(0))
goto fail; // escaping error
// without backslash escaping, both ' and " are used for single
@ -647,7 +647,7 @@ static void parse_function_call(void)
// make lower case version of name in local dynamic buffer
dynabuf_to_lower(function_dyna_buf, GlobalDynaBuf);
// search for tree item
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);
} else {
Throw_error("Unknown function.");
@ -685,7 +685,7 @@ static void list_append_list(struct listitem *selfhead, struct listitem *otherhe
struct listitem *item;
if (selfhead == otherhead)
Bug_found("ExtendingListWithItself", 0);
BUG("ExtendingListWithItself", 0);
item = otherhead->next;
while (item != otherhead) {
list_append_object(selfhead, &item->u.payload);
@ -717,7 +717,7 @@ static int parse_octal_or_unpseudo(void) // now GotByte = '&'
parse_program_counter(unpseudo_count);
} else if (BYTE_STARTS_KEYWORD(GotByte) || (GotByte == LOCAL_PREFIX) || (GotByte == CHEAP_PREFIX)) {
// symbol
if (Input_read_scope_and_symbol_name(&scope)) // now GotByte = illegal char
if (input_read_scope_and_symbol_name(&scope)) // now GotByte = illegal char
return 1; // error (no string given)
if ((GotByte == '?') && symbol_fix_dynamic_name())
@ -802,7 +802,7 @@ static void handle_special_operator(struct expression *expression, enum op_id pr
}
break;
default:
Bug_found("IllegalOperatorId", previous);
BUG("IllegalOperatorId", previous);
}
}
// put dyadic operator on stack and try to reduce stacks by performing
@ -835,7 +835,7 @@ static void push_dyadic_and_check(struct expression *expression, struct op *op)
case OPGROUP_MONADIC:
// stacks: ... ... previous op(monadic) newest arg newest op(dyadic)
if (arg_sp < 1)
Bug_found("ArgStackEmpty", arg_sp);
BUG("ArgStackEmpty", arg_sp);
NEWEST_ARGUMENT.type->monadic_op(&NEWEST_ARGUMENT, PREVIOUS_OPERATOR);
expression->is_parenthesized = FALSE; // operation was something other than parentheses
// now remove previous operator by overwriting with newest one...
@ -845,7 +845,7 @@ static void push_dyadic_and_check(struct expression *expression, struct op *op)
case OPGROUP_DYADIC:
// stacks: previous arg previous op(dyadic) newest arg newest op(dyadic)
if (arg_sp < 2)
Bug_found("NotEnoughArgs", arg_sp);
BUG("NotEnoughArgs", arg_sp);
PREVIOUS_ARGUMENT.type->dyadic_op(&PREVIOUS_ARGUMENT, PREVIOUS_OPERATOR, &NEWEST_ARGUMENT);
expression->is_parenthesized = FALSE; // operation was something other than parentheses
// now remove previous operator by overwriting with newest one...
@ -856,12 +856,12 @@ static void push_dyadic_and_check(struct expression *expression, struct op *op)
case OPGROUP_SPECIAL:
// stacks: ... ... previous op(special) newest arg newest op(dyadic)
if (NEWEST_OPERATOR->id != OPID_TERMINATOR)
Bug_found("StrangeOperator", NEWEST_OPERATOR->id);
BUG("StrangeOperator", NEWEST_OPERATOR->id);
handle_special_operator(expression, PREVIOUS_OPERATOR->id);
// the function above fixes both stacks and "is_parenthesized"!
break;
default:
Bug_found("IllegalOperatorGroup", PREVIOUS_OPERATOR->group);
BUG("IllegalOperatorGroup", PREVIOUS_OPERATOR->group);
}
}
}
@ -986,7 +986,7 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
}
// here we need to put '.' into GlobalDynaBuf even though we have already skipped it:
if (Input_read_scope_and_symbol_name_KLUGED(&scope) == 0) { // now GotByte = illegal char
if (input_read_scope_and_symbol_name_KLUGED(&scope) == 0) { // now GotByte = illegal char
if ((GotByte == '?') && symbol_fix_dynamic_name()) {
alu_state = STATE_ERROR;
break;//goto done;
@ -1000,7 +1000,7 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
break;//goto done;
case CHEAP_PREFIX: // cheap local symbol
//printf("looking in cheap scope %d\n", section_now->cheap_scope);
if (Input_read_scope_and_symbol_name(&scope) == 0) { // now GotByte = illegal char
if (input_read_scope_and_symbol_name(&scope) == 0) { // now GotByte = illegal char
if ((GotByte == '?') && symbol_fix_dynamic_name()) {
alu_state = STATE_ERROR;
break;//goto done;
@ -1024,7 +1024,7 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
register int length;
// Read global label (or "NOT")
length = Input_read_keyword();
length = input_read_keyword();
// Now GotByte = illegal char
// Check for NOT. Okay, it's hardcoded,
// but so what? Sue me...
@ -1209,10 +1209,10 @@ static void expect_dyadic_operator(struct expression *expression)
default:
// check string versions of operators
if (BYTE_STARTS_KEYWORD(GotByte)) {
Input_read_and_lower_keyword();
input_read_and_lower_keyword();
// Now GotByte = illegal char
// search for tree item
if (Tree_easy_scan(op_tree, &node_body, GlobalDynaBuf)) {
if (tree_easy_scan(op_tree, &node_body, GlobalDynaBuf)) {
op = node_body;
goto push_dyadic_op;
}
@ -1227,7 +1227,7 @@ static void expect_dyadic_operator(struct expression *expression)
}
}
//end:
return; // TODO - change the two points that go here and add a Bug_found() instead
return; // TODO - change the two points that go here and add a BUG() instead
// shared endings
get_byte_and_push_dyadic:
@ -1242,10 +1242,10 @@ static void unsupported_operation(const struct object *optional, const struct op
{
if (optional) {
if (op->group != OPGROUP_DYADIC)
Bug_found("OperatorIsNotDyadic", op->id);
BUG("OperatorIsNotDyadic", op->id);
} else {
if (op->group != OPGROUP_MONADIC)
Bug_found("OperatorIsNotMonadic", op->id);
BUG("OperatorIsNotMonadic", op->id);
}
dynabuf_clear(errormsg_dyna_buf);
dynabuf_add_string(errormsg_dyna_buf, "Operation not supported: Cannot apply \"");
@ -1387,7 +1387,7 @@ static boolean list_differs(const struct object *self, const struct object *othe
ford = other->u.listhead->next;
while (arthur != self->u.listhead) {
if (ford == other->u.listhead)
Bug_found("ListLengthError", 0);
BUG("ListLengthError", 0);
if (arthur->u.payload.type != ford->u.payload.type)
return TRUE; // item types differ
@ -1398,7 +1398,7 @@ static boolean list_differs(const struct object *self, const struct object *othe
ford = ford->next;
}
if (ford != other->u.listhead)
Bug_found("ListLengthError", 1);
BUG("ListLengthError", 1);
return FALSE; // no difference found
}
// string:
@ -1685,7 +1685,7 @@ static void number_handle_monadic_operator(struct object *self, const struct op
float_handle_monadic_operator(self, op);
break;
default:
Bug_found("IllegalNumberType1", self->u.number.ntype);
BUG("IllegalNumberType1", self->u.number.ntype);
}
}
@ -1888,7 +1888,7 @@ static void int_handle_dyadic_operator(struct object *self, const struct op *op,
// maybe put this into an extra "int_dyadic_int" function?
// sanity check, now "other" must be an int
if (other->u.number.ntype != NUMTYPE_INT)
Bug_found("SecondArgIsNotAnInt", op->id);
BUG("SecondArgIsNotAnInt", op->id);
// part 2: now we got rid of non-ints, perform actual operation:
switch (op->id) {
@ -2150,7 +2150,7 @@ static void number_handle_dyadic_operator(struct object *self, const struct op *
else if (self->u.number.ntype == NUMTYPE_FLOAT)
float_handle_dyadic_operator(self, op, other);
else
Bug_found("IllegalNumberType2", self->u.number.ntype);
BUG("IllegalNumberType2", self->u.number.ntype);
}
@ -2171,7 +2171,7 @@ static int get_valid_index(int *target, int length, const struct object *self, c
if (other->u.number.ntype == NUMTYPE_FLOAT)
float_to_int(other);
if (other->u.number.ntype != NUMTYPE_INT)
Bug_found("IllegalNumberType3", other->u.number.ntype);
BUG("IllegalNumberType3", other->u.number.ntype);
index = other->u.number.val.intval;
// negative indices access from the end
@ -2337,7 +2337,7 @@ static void number_print(const struct object *self, struct dynabuf *db)
sprintf(buffer, "%.30g", self->u.number.val.fpval);
dynabuf_add_string(db, buffer);
} else {
Bug_found("IllegalNumberType5", self->u.number.ntype);
BUG("IllegalNumberType5", self->u.number.ntype);
}
}
@ -2395,7 +2395,7 @@ static int string_get_length(const struct object *self)
// cannot be indexed
static void cannot_be_indexed(const struct object *self, struct object *target, int index)
{
Bug_found("TriedToIndexNumber", index);
BUG("TriedToIndexNumber", index);
}
// list:
@ -2499,9 +2499,9 @@ static int parse_expression(struct expression *expression)
if (alu_state == STATE_END) {
// check for bugs
if (arg_sp != 1)
Bug_found("ArgStackNotEmpty", arg_sp);
BUG("ArgStackNotEmpty", arg_sp);
if (op_sp != 1)
Bug_found("OperatorStackNotEmpty", op_sp);
BUG("OperatorStackNotEmpty", op_sp);
// copy result
*result = arg_stack[0];
// if there was nothing to parse, mark as undefined FIXME - change this! make "nothing" its own result type; only numbers may be undefined
@ -2531,10 +2531,10 @@ static int parse_expression(struct expression *expression)
//result->u.number.val.intval = 0;
result->u.number.addr_refs = 0;
// make sure no additional (spurious) errors are reported:
Input_skip_remainder();
input_skip_remainder();
// FIXME - remove this when new function interface gets used:
// callers must decide for themselves what to do when expression
// parser returns error (and may decide to call Input_skip_remainder)
// parser returns error (and may decide to call input_skip_remainder)
return 1; // error
}
}
@ -2563,7 +2563,7 @@ void ALU_any_int(intval_t *target) // ACCEPT_UNDEFINED
else if (expression.result.u.number.ntype == NUMTYPE_FLOAT)
*target = expression.result.u.number.val.fpval;
else
Bug_found("IllegalNumberType6", expression.result.u.number.ntype);
BUG("IllegalNumberType6", expression.result.u.number.ntype);
} else if (expression.result.type == &type_string) {
// accept single-char strings, to be more
// compatible with versions before 0.97:
@ -2618,7 +2618,7 @@ throws errors even though the result is defined!
} else if (expression.result.u.number.ntype == NUMTYPE_FLOAT) {
float_to_int(&expression.result);
} else {
Bug_found("IllegalNumberType7", expression.result.u.number.ntype);
BUG("IllegalNumberType7", expression.result.u.number.ntype);
}
} else if (expression.result.type == &type_string) {
// accept single-char strings, to be more

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// CPU type stuff
@ -96,7 +96,7 @@ const struct cpu_type *cputype_find(void)
void *node_body;
// perform lookup
if (!Tree_easy_scan(cputype_tree, &node_body, GlobalDynaBuf))
if (!tree_easy_scan(cputype_tree, &node_body, GlobalDynaBuf))
return NULL;
return node_body;

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Character encoding stuff
@ -121,7 +121,7 @@ const struct encoder *encoding_find(void)
void *node_body;
// perform lookup
if (!Tree_easy_scan(encoder_tree, &node_body, GlobalDynaBuf)) {
if (!tree_easy_scan(encoder_tree, &node_body, GlobalDynaBuf)) {
Throw_error("Unknown encoding.");
return NULL;
}

View File

@ -35,18 +35,18 @@ boolean check_ifdef_condition(void)
struct symbol *symbol;
// read symbol name
if (Input_read_scope_and_symbol_name(&scope)) // skips spaces before
if (input_read_scope_and_symbol_name(&scope)) // skips spaces before
return FALSE; // there was an error, it has been reported, so return value is more or less meaningless anway
// look for it
Tree_hard_scan(&node, symbols_forest, scope, FALSE);
tree_hard_scan(&node, symbols_forest, scope, FALSE);
if (!node)
return FALSE; // not found -> no, not defined
symbol = (struct symbol *) node->body;
symbol->has_been_read = TRUE; // we did not really read the symbol's value, but checking for its existence still counts as "used it"
if (symbol->object.type == NULL)
Bug_found("ObjectHasNullType", 0);
BUG("ObjectHasNullType", 0);
return symbol->object.type->is_defined(&symbol->object);
}
@ -54,12 +54,12 @@ boolean check_ifdef_condition(void)
// parse a loop body (TODO - also use for macro body?)
static void parse_ram_block(struct block *block)
{
Input_now->line_number = block->start; // set line number to loop start
Input_now->src.ram_ptr = block->body; // set RAM read pointer to loop
input_now->line_number = block->start; // set line number to loop start
input_now->src.ram_ptr = block->body; // set RAM read pointer to loop
// parse block
Parse_until_eob_or_eof();
parse_until_eob_or_eof();
if (GotByte != CHAR_EOB)
Bug_found("IllegalBlockTerminator", GotByte);
BUG("IllegalBlockTerminator", GotByte);
}
@ -124,15 +124,15 @@ void flow_forloop(struct for_loop *loop)
// switching input makes us lose GotByte. But we know it's '}' anyway!
// set up new input
loop_input = *Input_now; // copy current input structure into new
loop_input = *input_now; // copy current input structure into new
loop_input.source = INPUTSRC_RAM; // set new byte source
// remember old input
outer_input = Input_now;
outer_input = input_now;
// activate new input
// (not yet useable; pointer and line number are still missing)
Input_now = &loop_input;
input_now = &loop_input;
// fix line number (not for block, but in case symbol handling throws errors)
Input_now->line_number = loop->block.start;
input_now->line_number = loop->block.start;
switch (loop->algorithm) {
case FORALGO_OLDCOUNT:
case FORALGO_NEWCOUNT:
@ -142,10 +142,10 @@ void flow_forloop(struct for_loop *loop)
iterating_for(loop);
break;
default:
Bug_found("IllegalLoopAlgo", loop->algorithm);
BUG("IllegalLoopAlgo", loop->algorithm);
}
// restore previous input:
Input_now = outer_input;
input_now = outer_input;
}
@ -160,7 +160,7 @@ static void copy_condition(struct condition *condition, char terminator)
// append to GlobalDynaBuf and check for quotes
DYNABUF_APPEND(GlobalDynaBuf, GotByte);
if ((GotByte == '"') || (GotByte == '\'')) {
err = Input_quoted_to_dynabuf(GotByte);
err = input_quoted_to_dynabuf(GotByte);
// here GotByte changes, it might become CHAR_EOS
DYNABUF_APPEND(GlobalDynaBuf, GotByte); // add closing quotes (or CHAR_EOS) as well
if (err)
@ -179,7 +179,7 @@ static void copy_condition(struct condition *condition, char terminator)
void flow_store_doloop_condition(struct condition *condition, char terminator)
{
// write line number
condition->line = Input_now->line_number;
condition->line = input_now->line_number;
// set defaults
condition->invert = FALSE;
condition->body = NULL;
@ -188,7 +188,7 @@ void flow_store_doloop_condition(struct condition *condition, char terminator)
return;
// seems as if there really *is* a condition, so check for until/while
if (Input_read_and_lower_keyword()) {
if (input_read_and_lower_keyword()) {
if (strcmp(GlobalDynaBuf->buffer, "while") == 0) {
//condition.invert = FALSE;
} else if (strcmp(GlobalDynaBuf->buffer, "until") == 0) {
@ -208,7 +208,7 @@ void flow_store_doloop_condition(struct condition *condition, char terminator)
// call with GotByte = first interesting character
void flow_store_while_condition(struct condition *condition)
{
condition->line = Input_now->line_number;
condition->line = input_now->line_number;
condition->invert = FALSE;
copy_condition(condition, CHAR_SOB);
}
@ -224,8 +224,8 @@ static boolean check_condition(struct condition *condition)
return TRUE; // non-existing conditions are always true
// set up input for expression evaluation
Input_now->line_number = condition->line;
Input_now->src.ram_ptr = condition->body;
input_now->line_number = condition->line;
input_now->src.ram_ptr = condition->body;
GetByte(); // proceed with next char
ALU_defined_int(&intresult);
if (GotByte)
@ -241,13 +241,13 @@ void flow_do_while(struct do_while *loop)
struct input *outer_input;
// set up new input
loop_input = *Input_now; // copy current input structure into new
loop_input = *input_now; // copy current input structure into new
loop_input.source = INPUTSRC_RAM; // set new byte source
// remember old input
outer_input = Input_now;
outer_input = input_now;
// activate new input (not useable yet, as pointer and
// line number are not yet set up)
Input_now = &loop_input;
input_now = &loop_input;
for (;;) {
// check head condition
if (!check_condition(&loop->head_cond))
@ -258,7 +258,7 @@ void flow_do_while(struct do_while *loop)
break;
}
// restore previous input:
Input_now = outer_input;
input_now = outer_input;
GotByte = CHAR_EOS; // CAUTION! Very ugly kluge.
// But by switching input, we lost the outer input's GotByte. We know
// it was CHAR_EOS. We could just call GetByte() to get real input, but
@ -274,11 +274,11 @@ void flow_parse_and_close_file(FILE *fd, const char *filename)
if (config.process_verbosity > 2)
printf("Parsing source file '%s'\n", filename);
// set up new input
Input_new_file(filename, fd);
// Parse block and check end reason
Parse_until_eob_or_eof();
input_new_file(filename, fd);
// parse block and check end reason
parse_until_eob_or_eof();
if (GotByte != CHAR_EOF)
Throw_error("Found '}' instead of end-of-file.");
// close sublevel src
fclose(Input_now->src.fd);
fclose(input_now->src.fd);
}

View File

@ -143,7 +143,7 @@ static int first_label_of_statement(bits *statement_flags)
{
if ((*statement_flags) & SF_IMPLIED_LABEL) {
Throw_error(exception_syntax);
Input_skip_remainder();
input_skip_remainder();
return FALSE;
}
(*statement_flags) |= SF_IMPLIED_LABEL; // now there has been one
@ -211,11 +211,11 @@ static void parse_symbol_definition(scope_t scope, bits stat_flags)
if (GotByte == '?')
symbol_fix_dynamic_name();
force_bit = Input_get_force_bit(); // skips spaces after (yes, force bit is allowed for label definitions)
force_bit = input_get_force_bit(); // skips spaces after (yes, force bit is allowed for label definitions)
if (GotByte == '=') {
// explicit symbol definition (symbol = <something>)
parse_assignment(scope, force_bit, POWER_NONE);
Input_ensure_EOS();
input_ensure_EOS();
} else {
// implicit symbol definition (label)
set_label(scope, stat_flags, force_bit, POWER_NONE);
@ -228,7 +228,7 @@ static void parse_mnemo_or_global_symbol_def(bits *statement_flags)
{
boolean is_mnemonic;
is_mnemonic = CPU_state.type->keyword_is_mnemonic(Input_read_keyword());
is_mnemonic = CPU_state.type->keyword_is_mnemonic(input_read_keyword());
// It is only a label if it isn't a mnemonic
if ((!is_mnemonic)
&& first_label_of_statement(statement_flags)) {
@ -251,7 +251,7 @@ static void parse_local_symbol_def(bits *statement_flags)
if (!first_label_of_statement(statement_flags))
return;
if (Input_read_scope_and_symbol_name(&scope) == 0)
if (input_read_scope_and_symbol_name(&scope) == 0)
parse_symbol_definition(scope, *statement_flags);
}
@ -294,7 +294,7 @@ static void parse_forward_anon_def(bits *statement_flags)
// Parse block, beginning with next byte.
// End reason (either CHAR_EOB or CHAR_EOF) can be found in GotByte afterwards
// Has to be re-entrant.
void Parse_until_eob_or_eof(void)
void parse_until_eob_or_eof(void)
{
bits statement_flags;
@ -335,7 +335,7 @@ void Parse_until_eob_or_eof(void)
if ((GotByte == LOCAL_PREFIX)
|| (GotByte == CHEAP_PREFIX)
|| (BYTE_CONTINUES_KEYWORD(GotByte)))
Macro_parse_call();
macro_parse_call();
else
parse_forward_anon_def(&statement_flags);
break;
@ -351,7 +351,7 @@ void Parse_until_eob_or_eof(void)
parse_mnemo_or_global_symbol_def(&statement_flags);
} else {
Throw_error(exception_syntax);
Input_skip_remainder();
input_skip_remainder();
}
}
}
@ -366,12 +366,12 @@ void Parse_until_eob_or_eof(void)
// Skip space. If GotByte is CHAR_SOB ('{'), parse block and return TRUE.
// Otherwise (if there is no block), return FALSE.
// Don't forget to call EnsureEOL() afterwards.
int Parse_optional_block(void)
int parse_optional_block(void)
{
SKIPSPACE();
if (GotByte != CHAR_SOB)
return FALSE;
Parse_until_eob_or_eof();
parse_until_eob_or_eof();
if (GotByte != CHAR_EOB)
Throw_serious_error(exception_no_right_brace);
GetByte();
@ -397,11 +397,11 @@ static void throw_message(const char *message, const char *type)
++throw_counter;
if (config.format_msvc)
fprintf(config.msg_stream, "%s(%d) : %s (%s %s): %s\n",
Input_now->original_filename, Input_now->line_number,
input_now->original_filename, input_now->line_number,
type, section_now->type, section_now->title, message);
else
fprintf(config.msg_stream, "%s - File %s, line %d (%s %s): %s\n",
type, Input_now->original_filename, Input_now->line_number,
type, input_now->original_filename, input_now->line_number,
section_now->type, section_now->title, message);
}
@ -461,7 +461,7 @@ void Throw_serious_error(const char *message)
// Handle bugs
void Bug_found(const char *message, int code)
void BUG(const char *message, int code)
{
Throw_warning("Bug in ACME, code follows");
fprintf(stderr, "(0x%x:)", code);
@ -484,7 +484,7 @@ void output_object(struct object *object, struct iter_context *iter)
else if (object->u.number.ntype == NUMTYPE_FLOAT)
iter->fn(object->u.number.val.fpval);
else
Bug_found("IllegalNumberType0", object->u.number.ntype);
BUG("IllegalNumberType0", object->u.number.ntype);
} else if (object->type == &type_list) {
// iterate over list
item = object->u.listhead->next;
@ -505,7 +505,7 @@ void output_object(struct object *object, struct iter_context *iter)
Throw_error("There's more than one character."); // see alu.c for the original of this error
}
} else {
Bug_found("IllegalObjectType", 0);
BUG("IllegalObjectType", 0);
}
}
@ -515,7 +515,7 @@ void output_8(intval_t value)
{
if ((value < -0x80) || (value > 0xff))
Throw_error(exception_number_out_of_8b_range);
Output_byte(value);
output_byte(value);
}
@ -524,8 +524,8 @@ void output_be16(intval_t value)
{
if ((value < -0x8000) || (value > 0xffff))
Throw_error(exception_number_out_of_16b_range);
Output_byte(value >> 8);
Output_byte(value);
output_byte(value >> 8);
output_byte(value);
}
@ -534,8 +534,8 @@ void output_le16(intval_t value)
{
if ((value < -0x8000) || (value > 0xffff))
Throw_error(exception_number_out_of_16b_range);
Output_byte(value);
Output_byte(value >> 8);
output_byte(value);
output_byte(value >> 8);
}
@ -544,9 +544,9 @@ void output_be24(intval_t value)
{
if ((value < -0x800000) || (value > 0xffffff))
Throw_error(exception_number_out_of_24b_range);
Output_byte(value >> 16);
Output_byte(value >> 8);
Output_byte(value);
output_byte(value >> 16);
output_byte(value >> 8);
output_byte(value);
}
@ -555,9 +555,9 @@ void output_le24(intval_t value)
{
if ((value < -0x800000) || (value > 0xffffff))
Throw_error(exception_number_out_of_24b_range);
Output_byte(value);
Output_byte(value >> 8);
Output_byte(value >> 16);
output_byte(value);
output_byte(value >> 8);
output_byte(value >> 16);
}
@ -572,10 +572,10 @@ void output_be32(intval_t value)
{
// if ((value < -0x80000000) || (value > 0xffffffff))
// Throw_error(exception_number_out_of_32b_range);
Output_byte(value >> 24);
Output_byte(value >> 16);
Output_byte(value >> 8);
Output_byte(value);
output_byte(value >> 24);
output_byte(value >> 16);
output_byte(value >> 8);
output_byte(value);
}
@ -584,8 +584,8 @@ void output_le32(intval_t value)
{
// if ((value < -0x80000000) || (value > 0xffffffff))
// Throw_error(exception_number_out_of_32b_range);
Output_byte(value);
Output_byte(value >> 8);
Output_byte(value >> 16);
Output_byte(value >> 24);
output_byte(value);
output_byte(value >> 8);
output_byte(value >> 16);
output_byte(value >> 24);
}

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Global stuff - things that are needed by several modules
@ -121,41 +121,52 @@ do { \
// set configuration to default values
extern void config_default(struct config *conf);
// allocate memory and die if not available
extern void *safe_malloc(size_t amount);
// call with symbol name in GlobalDynaBuf and GotByte == '='
// "powers" is for "!set" pseudo opcode so changes are allowed (see symbol.h for powers)
extern void parse_assignment(scope_t scope, bits force_bit, bits powers);
// Parse block, beginning with next byte.
// End reason (either CHAR_EOB or CHAR_EOF) can be found in GotByte afterwards
// Has to be re-entrant.
extern void Parse_until_eob_or_eof(void);
extern void parse_until_eob_or_eof(void);
// Skip space. If GotByte is CHAR_SOB ('{'), parse block and return TRUE.
// Otherwise (if there is no block), return FALSE.
// Don't forget to call EnsureEOL() afterwards.
extern int Parse_optional_block(void);
extern int parse_optional_block(void);
// error/warning counter so macro calls can find out whether to show a call stack
extern int Throw_get_counter(void);
// Output a warning.
// This means the produced code looks as expected. But there has been a
// situation that should be reported to the user, for example ACME may have
// assembled a 16-bit parameter with an 8-bit value.
extern void Throw_warning(const char *msg);
// Output a warning if in first pass. See above.
extern void Throw_first_pass_warning(const char *msg);
// Output an error.
// This means something went wrong in a way that implies that the output
// almost for sure won't look like expected, for example when there was a
// syntax error. The assembler will try to go on with the assembly though, so
// the user gets to know about more than one of his typos at a time.
extern void Throw_error(const char *msg);
// Output a serious error, stopping assembly.
// Serious errors are those that make it impossible to go on with the
// assembly. Example: "!fill" without a parameter - the program counter cannot
// be set correctly in this case, so proceeding would be of no use at all.
extern void Throw_serious_error(const char *msg);
// handle bugs
extern void Bug_found(const char *msg, int code);
extern void BUG(const char *msg, int code);
// insert object (in case of list, will iterate/recurse until done)
struct iter_context {
void (*fn)(intval_t); // output function
@ -163,21 +174,27 @@ struct iter_context {
unsigned char stringxor; // for !scrxor, 0 otherwise
};
extern void output_object(struct object *object, struct iter_context *iter);
// output 8-bit value with range check
extern void output_8(intval_t value);
// output 16-bit value with range check big-endian
extern void output_be16(intval_t value);
// output 16-bit value with range check little-endian
extern void output_le16(intval_t value);
// output 24-bit value with range check big-endian
extern void output_be24(intval_t value);
// output 24-bit value with range check little-endian
extern void output_le24(intval_t value);
// output 32-bit value (without range check) big-endian
extern void output_be32(intval_t value);
// output 32-bit value (without range check) little-endian
extern void output_le32(intval_t value);
#endif

View File

@ -37,19 +37,19 @@ static struct input outermost = {
// variables
struct input *Input_now = &outermost; // current input structure
struct input *input_now = &outermost; // current input structure
// functions
// let current input point to start of file
void Input_new_file(const char *filename, FILE *fd)
void input_new_file(const char *filename, FILE *fd)
{
Input_now->original_filename = filename;
Input_now->line_number = 1;
Input_now->source = INPUTSRC_FILE;
Input_now->state = INPUTSTATE_SOF;
Input_now->src.fd = fd;
input_now->original_filename = filename;
input_now->line_number = 1;
input_now->source = INPUTSRC_FILE;
input_now->state = INPUTSTATE_SOF;
input_now->src.fd = fd;
}
@ -64,9 +64,9 @@ static void report_srcchar(char new_char)
char hexdump[2 * REPORT_BINBUFSIZE + 2]; // +2 for '.' and terminator
// if input has changed, insert explanation
if (Input_now != report->last_input) {
fprintf(report->fd, "\n; ******** Source: %s\n", Input_now->original_filename);
report->last_input = Input_now;
if (input_now != report->last_input) {
fprintf(report->fd, "\n; ******** Source: %s\n", input_now->original_filename);
report->last_input = input_now;
report->asc_used = 0; // clear buffer
prev_char = '\0';
}
@ -74,7 +74,7 @@ static void report_srcchar(char new_char)
// line start after line break detected and EOS processed,
// build report line:
// show line number...
fprintf(report->fd, "%6d ", Input_now->line_number - 1);
fprintf(report->fd, "%6d ", input_now->line_number - 1);
// prepare outbytes' start address
if (report->bin_used) {
#if _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L
@ -117,23 +117,23 @@ static char get_processed_from_file(void)
static int from_file = 0;
for (;;) {
switch (Input_now->state) {
switch (input_now->state) {
case INPUTSTATE_SOF:
// fetch first byte from the current source file
from_file = getc(Input_now->src.fd);
from_file = getc(input_now->src.fd);
IF_WANTED_REPORT_SRCCHAR(from_file);
//TODO - check for bogus/malformed BOM (0xef 0xbb 0xbf as UTF-8-encoded 0xfeff) and ignore?
// check for hashbang line and ignore
if (from_file == '#') {
// remember to skip remainder of line
Input_now->state = INPUTSTATE_COMMENT;
input_now->state = INPUTSTATE_COMMENT;
return CHAR_EOS; // end of statement
}
Input_now->state = INPUTSTATE_AGAIN;
input_now->state = INPUTSTATE_AGAIN;
break;
case INPUTSTATE_NORMAL:
// fetch a fresh byte from the current source file
from_file = getc(Input_now->src.fd);
from_file = getc(input_now->src.fd);
IF_WANTED_REPORT_SRCCHAR(from_file);
// now process it
/*FALLTHROUGH*/
@ -144,12 +144,12 @@ static char get_processed_from_file(void)
// If the source is changed so there is a possibility
// to enter INPUTSTATE_AGAIN mode without first having
// defined "from_file", trouble may arise...
Input_now->state = INPUTSTATE_NORMAL;
input_now->state = INPUTSTATE_NORMAL;
// EOF must be checked first because it cannot be used
// as an index into global_byte_flags[]
if (from_file == EOF) {
// remember to send an end-of-file
Input_now->state = INPUTSTATE_EOF;
input_now->state = INPUTSTATE_EOF;
return CHAR_EOS; // end of statement
}
@ -163,38 +163,38 @@ static char get_processed_from_file(void)
case '\t':
case ' ':
// remember to skip all following blanks
Input_now->state = INPUTSTATE_SKIPBLANKS;
input_now->state = INPUTSTATE_SKIPBLANKS;
return ' ';
case CHAR_LF: // LF character
// remember to send a start-of-line
Input_now->state = INPUTSTATE_LF;
input_now->state = INPUTSTATE_LF;
return CHAR_EOS; // end of statement
case CHAR_CR: // CR character
// remember to check CRLF + send start-of-line
Input_now->state = INPUTSTATE_CR;
input_now->state = INPUTSTATE_CR;
return CHAR_EOS; // end of statement
case CHAR_EOB:
// remember to send an end-of-block
Input_now->state = INPUTSTATE_EOB;
input_now->state = INPUTSTATE_EOB;
return CHAR_EOS; // end of statement
case '/':
// to check for "//", get another byte:
from_file = getc(Input_now->src.fd);
from_file = getc(input_now->src.fd);
IF_WANTED_REPORT_SRCCHAR(from_file);
if (from_file != '/') {
// not "//", so:
Input_now->state = INPUTSTATE_AGAIN; // second byte must be parsed normally later on
input_now->state = INPUTSTATE_AGAIN; // second byte must be parsed normally later on
return '/'; // first byte is returned normally right now
}
// it's really "//", so act as if ';'
/*FALLTHROUGH*/
case ';':
// remember to skip remainder of line
Input_now->state = INPUTSTATE_COMMENT;
input_now->state = INPUTSTATE_COMMENT;
return CHAR_EOS; // end of statement
case ':': // statement delimiter
@ -209,60 +209,60 @@ static char get_processed_from_file(void)
case INPUTSTATE_SKIPBLANKS:
// read until non-blank, then deliver that
do {
from_file = getc(Input_now->src.fd);
from_file = getc(input_now->src.fd);
IF_WANTED_REPORT_SRCCHAR(from_file);
} while ((from_file == '\t') || (from_file == ' '));
// re-process last byte
Input_now->state = INPUTSTATE_AGAIN;
input_now->state = INPUTSTATE_AGAIN;
break;
case INPUTSTATE_LF:
// return start-of-line, then continue in normal mode
Input_now->state = INPUTSTATE_NORMAL;
input_now->state = INPUTSTATE_NORMAL;
return CHAR_SOL; // new line
case INPUTSTATE_CR:
// return start-of-line, remember to check for LF
Input_now->state = INPUTSTATE_SKIPLF;
input_now->state = INPUTSTATE_SKIPLF;
return CHAR_SOL; // new line
case INPUTSTATE_SKIPLF:
from_file = getc(Input_now->src.fd);
from_file = getc(input_now->src.fd);
IF_WANTED_REPORT_SRCCHAR(from_file);
// if LF, ignore it and fetch another byte
// otherwise, process current byte
if (from_file == CHAR_LF)
Input_now->state = INPUTSTATE_NORMAL;
input_now->state = INPUTSTATE_NORMAL;
else
Input_now->state = INPUTSTATE_AGAIN;
input_now->state = INPUTSTATE_AGAIN;
break;
case INPUTSTATE_COMMENT:
// read until end-of-line or end-of-file
do {
from_file = getc(Input_now->src.fd);
from_file = getc(input_now->src.fd);
IF_WANTED_REPORT_SRCCHAR(from_file);
} while ((from_file != EOF) && (from_file != CHAR_CR) && (from_file != CHAR_LF));
// re-process last byte
Input_now->state = INPUTSTATE_AGAIN;
input_now->state = INPUTSTATE_AGAIN;
break;
case INPUTSTATE_EOB:
// deliver EOB
Input_now->state = INPUTSTATE_NORMAL;
input_now->state = INPUTSTATE_NORMAL;
return CHAR_EOB; // end of block
case INPUTSTATE_EOF:
// deliver EOF
Input_now->state = INPUTSTATE_NORMAL;
input_now->state = INPUTSTATE_NORMAL;
return CHAR_EOF; // end of file
default:
Bug_found("StrangeInputMode", Input_now->state);
BUG("StrangeInputMode", input_now->state);
}
}
}
// This function delivers the next byte from the currently active byte source
// in shortened high-level format. FIXME - use fn ptr?
// When inside quotes, use Input_quoted_to_dynabuf() instead!
// When inside quotes, use input_quoted_to_dynabuf() instead!
char GetByte(void)
{
// for (;;) {
@ -271,23 +271,23 @@ char GetByte(void)
// high-level format
// Otherwise, the source is a file. This means we will call
// get_processed_from_file() which will do a shit load of conversions.
switch (Input_now->source) {
switch (input_now->source) {
case INPUTSRC_RAM:
GotByte = *(Input_now->src.ram_ptr++);
GotByte = *(input_now->src.ram_ptr++);
break;
case INPUTSRC_FILE:
GotByte = get_processed_from_file();
break;
default:
Bug_found("IllegalInputSrc", Input_now->source);
BUG("IllegalInputSrc", input_now->source);
}
// // if start-of-line was read, increment line counter and repeat
// if (GotByte != CHAR_SOL)
// return GotByte;
// Input_now->line_number++;
// input_now->line_number++;
// }
if (GotByte == CHAR_SOL)
Input_now->line_number++;
input_now->line_number++;
return GotByte;
}
@ -299,30 +299,30 @@ static char GetQuotedByte(void)
{
int from_file; // must be an int to catch EOF
switch (Input_now->source) {
switch (input_now->source) {
case INPUTSRC_RAM:
// if byte source is RAM, then no conversion is necessary,
// because in RAM the source already has high-level format
GotByte = *(Input_now->src.ram_ptr++);
GotByte = *(input_now->src.ram_ptr++);
break;
case INPUTSRC_FILE:
// fetch a fresh byte from the current source file
from_file = getc(Input_now->src.fd);
from_file = getc(input_now->src.fd);
IF_WANTED_REPORT_SRCCHAR(from_file);
switch (from_file) {
case EOF:
// remember to send an end-of-file
Input_now->state = INPUTSTATE_EOF;
input_now->state = INPUTSTATE_EOF;
GotByte = CHAR_EOS; // end of statement
break;
case CHAR_LF: // LF character
// remember to send a start-of-line
Input_now->state = INPUTSTATE_LF;
input_now->state = INPUTSTATE_LF;
GotByte = CHAR_EOS; // end of statement
break;
case CHAR_CR: // CR character
// remember to check for CRLF + send a start-of-line
Input_now->state = INPUTSTATE_CR;
input_now->state = INPUTSTATE_CR;
GotByte = CHAR_EOS; // end of statement
break;
default:
@ -330,7 +330,7 @@ static char GetQuotedByte(void)
}
break;
default:
Bug_found("IllegalInputSrc", Input_now->source);
BUG("IllegalInputSrc", input_now->source);
}
// now check for end of statement
if (GotByte == CHAR_EOS)
@ -340,7 +340,7 @@ static char GetQuotedByte(void)
// Skip remainder of statement, for example on error
// FIXME - check for quotes, otherwise this might treat a quoted colon like EOS!
void Input_skip_remainder(void)
void input_skip_remainder(void)
{
while (GotByte)
GetByte(); // Read characters until end-of-statement
@ -348,7 +348,7 @@ void Input_skip_remainder(void)
// Ensure that the remainder of the current statement is empty, for example
// after mnemonics using implied addressing.
void Input_ensure_EOS(void) // Now GotByte = first char to test
void input_ensure_EOS(void) // Now GotByte = first char to test
{
SKIPSPACE();
if (GotByte) {
@ -359,13 +359,13 @@ void Input_ensure_EOS(void) // Now GotByte = first char to test
quote = (GotByte == '\'') ? '"' : '\''; // use single quotes, unless byte is a single quote (then use double quotes)
sprintf(buf, "Garbage data at end of statement (unexpected %c%c%c).", quote, GotByte, quote);
Throw_error(buf);
Input_skip_remainder();
input_skip_remainder();
}
}
// read string to dynabuf until closing quote is found
// returns 1 on errors (unterminated, escaping error)
int Input_quoted_to_dynabuf(char closing_quote)
int input_quoted_to_dynabuf(char closing_quote)
{
boolean escaped = FALSE;
@ -378,7 +378,7 @@ int Input_quoted_to_dynabuf(char closing_quote)
if (escaped) {
// previous byte was backslash, so do not check for terminator nor backslash
escaped = FALSE;
// do not actually _convert_ escape sequences to their target byte, that is done by Input_unescape_dynabuf() below!
// do not actually _convert_ escape sequences to their target byte, that is done by input_unescape_dynabuf() below!
// TODO - but maybe check for illegal escape sequences?
// at the moment checking is only done when the string
// gets used for something...
@ -396,8 +396,8 @@ int Input_quoted_to_dynabuf(char closing_quote)
// process backslash escapes in GlobalDynaBuf (so size might shrink)
// returns 1 on errors (escaping errors)
// TODO - check: if this is only ever called directly after Input_quoted_to_dynabuf, integrate that call here?
int Input_unescape_dynabuf(int read_index)
// TODO - check: if this is only ever called directly after input_quoted_to_dynabuf, integrate that call here?
int input_unescape_dynabuf(int read_index)
{
int write_index;
char byte;
@ -444,7 +444,7 @@ int Input_unescape_dynabuf(int read_index)
}
}
if (escaped)
Bug_found("PartialEscapeSequence", 0);
BUG("PartialEscapeSequence", 0);
GlobalDynaBuf->size = write_index;
return 0; // ok
}
@ -457,7 +457,7 @@ int Input_unescape_dynabuf(int read_index)
// After calling this function, GotByte holds '}'. Unless EOF was found first,
// but then a serious error would have been thrown.
// FIXME - use a struct block *ptr argument!
char *Input_skip_or_store_block(boolean store)
char *input_skip_or_store_block(boolean store)
{
char byte;
int depth = 1; // to find matching block end
@ -475,7 +475,7 @@ char *Input_skip_or_store_block(boolean store)
case '"': // Quotes? Okay, read quoted stuff.
case '\'':
Input_quoted_to_dynabuf(byte);
input_quoted_to_dynabuf(byte);
DYNABUF_APPEND(GlobalDynaBuf, GotByte); // add closing quote
break;
case CHAR_SOB:
@ -520,7 +520,7 @@ static int append_keyword_to_global_dynabuf(void)
// appending while characters are legal for keywords.
// throw "missing string" error if none.
// return whether there was an error.
int Input_append_symbol_name_to_global_dynabuf(void)
int input_append_symbol_name_to_global_dynabuf(void)
{
if ((GotByte == LOCAL_PREFIX)
|| (GotByte == CHEAP_PREFIX)) {
@ -536,7 +536,7 @@ int Input_append_symbol_name_to_global_dynabuf(void)
// read symbol name into GlobalDynaBuf, set scope,
// return whether there was an error (namely, "no string given").
int Input_readscopeandsymbolname(scope_t *scope, boolean dotkluge)
int input_readscopeandsymbolname(scope_t *scope, boolean dotkluge)
{
int err;
@ -550,7 +550,7 @@ int Input_readscopeandsymbolname(scope_t *scope, boolean dotkluge)
dynabuf_append(GlobalDynaBuf, '.');
err = append_keyword_to_global_dynabuf() == 0; // zero length -> error!
} else {
err = Input_append_symbol_name_to_global_dynabuf();
err = input_append_symbol_name_to_global_dynabuf();
}
// add terminator to buffer (increments buffer's length counter)
dynabuf_append(GlobalDynaBuf, '\0');
@ -572,7 +572,7 @@ int Input_readscopeandsymbolname(scope_t *scope, boolean dotkluge)
// character is read. Zero-terminate the string. Return its length (without
// terminator).
// Zero lengths will produce a "missing string" error.
int Input_read_keyword(void)
int input_read_keyword(void)
{
int length;
@ -587,7 +587,7 @@ int Input_read_keyword(void)
// character is read. Zero-terminate the string, then convert to lower case.
// Return its length (without terminator).
// Zero lengths will produce a "missing string" error.
int Input_read_and_lower_keyword(void)
int input_read_and_lower_keyword(void)
{
int length;
@ -607,8 +607,8 @@ int Input_read_and_lower_keyword(void)
// UNIX style to platform style.
// Returns nonzero on error. Filename in GlobalDynaBuf.
// Errors are handled and reported, but caller should call
// Input_skip_remainder() then.
int Input_read_filename(boolean allow_library, boolean *uses_lib)
// input_skip_remainder() then.
int input_read_filename(boolean allow_library, boolean *uses_lib)
{
int start_of_string;
char *lib_prefix,
@ -651,7 +651,7 @@ int Input_read_filename(boolean allow_library, boolean *uses_lib)
// remember border between optional library prefix and string from assembler source file
start_of_string = GlobalDynaBuf->size;
// read file name string
if (Input_quoted_to_dynabuf(terminator))
if (input_quoted_to_dynabuf(terminator))
return 1; // unterminated or escaping error
GetByte(); // eat terminator
@ -662,7 +662,7 @@ int Input_read_filename(boolean allow_library, boolean *uses_lib)
}
// resolve backslash escapes
if (Input_unescape_dynabuf(start_of_string))
if (input_unescape_dynabuf(start_of_string))
return 1; // escaping error
// terminate string
@ -676,7 +676,7 @@ int Input_read_filename(boolean allow_library, boolean *uses_lib)
// Try to read a comma, skipping spaces before and after. Return TRUE if comma
// found, otherwise FALSE.
int Input_accept_comma(void)
int input_accept_comma(void)
{
SKIPSPACE();
if (GotByte != ',')
@ -688,7 +688,7 @@ int Input_accept_comma(void)
// read optional info about parameter length
// FIXME - move to different file!
bits Input_get_force_bit(void)
bits input_get_force_bit(void)
{
char byte;
bits force_bit = 0;

View File

@ -55,29 +55,32 @@ extern const char FILE_READBINARY[];
// Variables
extern struct input *Input_now; // current input structure
extern struct input *input_now; // current input structure
// Prototypes
// let current input point to start of file
extern void Input_new_file(const char *filename, FILE *fd);
extern void input_new_file(const char *filename, FILE *fd);
// get next byte from currently active byte source in shortened high-level
// format. When inside quotes, use Input_quoted_to_dynabuf() instead!
// format. When inside quotes, use input_quoted_to_dynabuf() instead!
extern char GetByte(void);
// Skip remainder of statement, for example on error
extern void Input_skip_remainder(void);
extern void input_skip_remainder(void);
// Ensure that the remainder of the current statement is empty, for example
// after mnemonics using implied addressing.
extern void Input_ensure_EOS(void);
extern void input_ensure_EOS(void);
// read string to dynabuf until closing quote is found
// returns 1 on errors (unterminated, escaping error)
extern int Input_quoted_to_dynabuf(char closing_quote);
extern int input_quoted_to_dynabuf(char closing_quote);
// process backslash escapes in GlobalDynaBuf (so size might shrink)
// returns 1 on errors (escaping errors)
extern int Input_unescape_dynabuf(int start_index);
extern int input_unescape_dynabuf(int start_index);
// Skip or store block (starting with next byte, so call directly after
// reading opening brace).
@ -86,32 +89,33 @@ extern int Input_unescape_dynabuf(int start_index);
// If "Store" is FALSE, NULL is returned.
// After calling this function, GotByte holds '}'. Unless EOF was found first,
// but then a serious error would have been thrown.
extern char *Input_skip_or_store_block(boolean store);
extern char *input_skip_or_store_block(boolean store);
// append optional '.'/'@' prefix to GlobalDynaBuf, then keep
// appending while characters are legal for keywords.
// throw "missing string" error if none.
// return whether there was an error.
extern int Input_append_symbol_name_to_global_dynabuf(void);
extern int input_append_symbol_name_to_global_dynabuf(void);
// FIXME - move these to "symbol.h" and remove dependency on "scope":
// read symbol name into GlobalDynaBuf, set scope,
// return whether there was an error (namely, "no string given").
extern int Input_readscopeandsymbolname(scope_t *scope, boolean dotkluge);
#define Input_read_scope_and_symbol_name(scope) Input_readscopeandsymbolname(scope, FALSE)
#define Input_read_scope_and_symbol_name_KLUGED(scope) Input_readscopeandsymbolname(scope, TRUE)
extern int input_readscopeandsymbolname(scope_t *scope, boolean dotkluge);
#define input_read_scope_and_symbol_name(scope) input_readscopeandsymbolname(scope, FALSE)
#define input_read_scope_and_symbol_name_KLUGED(scope) input_readscopeandsymbolname(scope, TRUE)
// Clear dynamic buffer, then append to it until an illegal (for a keyword)
// character is read. Zero-terminate the string. Return its length (without
// terminator).
// Zero lengths will produce a "missing string" error.
extern int Input_read_keyword(void);
extern int input_read_keyword(void);
// Clear dynamic buffer, then append to it until an illegal (for a keyword)
// character is read. Zero-terminate the string, then convert to lower case.
// Return its length (without terminator).
// Zero lengths will produce a "missing string" error.
extern int Input_read_and_lower_keyword(void);
extern int input_read_and_lower_keyword(void);
// Try to read a file name.
// If "allow_library" is TRUE, library access by using <...> quoting
// is possible as well. If "uses_lib" is non-NULL, info about library
@ -120,19 +124,23 @@ extern int Input_read_and_lower_keyword(void);
// UNIX style to platform style.
// Returns nonzero on error. Filename in GlobalDynaBuf.
// Errors are handled and reported, but caller should call
// Input_skip_remainder() then.
extern int Input_read_filename(boolean library_allowed, boolean *uses_lib);
// input_skip_remainder() then.
extern int input_read_filename(boolean library_allowed, boolean *uses_lib);
// Try to read a comma, skipping spaces before and after. Return TRUE if comma
// found, otherwise FALSE.
extern int Input_accept_comma(void);
extern int input_accept_comma(void);
// read optional info about parameter length
extern bits Input_get_force_bit(void);
// FIXME - move to different file!
extern bits input_get_force_bit(void);
// include path stuff - should be moved to its own file:
// add entry
extern void includepaths_add(const char *path);
// open file for reading (trying list entries as prefixes)
// "uses_lib" tells whether to access library or to make use of include paths
// file name is expected in GlobalDynaBuf

View File

@ -74,7 +74,7 @@ static scope_t get_scope_and_title(void)
{
scope_t macro_scope;
Input_read_scope_and_symbol_name(&macro_scope); // skips spaces before
input_read_scope_and_symbol_name(&macro_scope); // skips spaces before
// now GotByte = illegal character after title
// copy macro title to private dynabuf and add separator character
dynabuf_clear(user_macro_name);
@ -92,7 +92,7 @@ static int pipe_comma(void)
{
int result;
result = Input_accept_comma();
result = input_accept_comma();
if (result)
DYNABUF_APPEND(GlobalDynaBuf, ',');
return result;
@ -112,7 +112,7 @@ static char *get_string_copy(const char *original)
// This function is called from both macro definition and macro call.
// Terminate macro name and copy from internal_name to GlobalDynaBuf
// (because that's where Tree_hard_scan() looks for the search string).
// (because that's where tree_hard_scan() looks for the search string).
// Then try to find macro and return whether it was created.
static int search_for_macro(struct rwnode **result, scope_t scope, int create)
{
@ -121,7 +121,7 @@ static int search_for_macro(struct rwnode **result, scope_t scope, int create)
dynabuf_clear(GlobalDynaBuf);
dynabuf_add_string(GlobalDynaBuf, internal_name->buffer);
dynabuf_append(GlobalDynaBuf, '\0');
return Tree_hard_scan(result, macro_forest, scope, create);
return tree_hard_scan(result, macro_forest, scope, create);
}
// This function is called when an already existing macro is re-defined.
@ -134,10 +134,10 @@ static void report_redefinition(struct rwnode *macro_node)
// show warning with location of current definition
Throw_warning(exception_macro_twice);
// CAUTION, ugly kluge: fiddle with Input_now and section_now
// CAUTION, ugly kluge: fiddle with input_now and section_now
// data to generate helpful error messages
Input_now->original_filename = original_macro->def_filename;
Input_now->line_number = original_macro->def_line_number;
input_now->original_filename = original_macro->def_filename;
input_now->line_number = original_macro->def_line_number;
section_now->type = "original";
section_now->title = "definition";
// show serious error with location of original definition
@ -147,7 +147,7 @@ static void report_redefinition(struct rwnode *macro_node)
// This function is only called during the first pass, so there's no need to
// check whether to skip the definition or not.
// Return with GotByte = '}'
void Macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
void macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
{
char *formal_parameters;
struct rwnode *macro_node;
@ -179,7 +179,7 @@ void Macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
GetByte();
}
// handle symbol name (including '.'/'@' prefix)
Input_append_symbol_name_to_global_dynabuf();
input_append_symbol_name_to_global_dynabuf();
} while (pipe_comma());
// ensure CHAR_SOB ('{')
if (GotByte != CHAR_SOB)
@ -198,17 +198,17 @@ void Macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
report_redefinition(macro_node); // quits with serious error
// Create new macro struct and set it up. Finally we'll read the body.
new_macro = safe_malloc(sizeof(*new_macro));
new_macro->def_line_number = Input_now->line_number;
new_macro->def_filename = get_string_copy(Input_now->original_filename);
new_macro->def_line_number = input_now->line_number;
new_macro->def_filename = get_string_copy(input_now->original_filename);
new_macro->original_name = get_string_copy(user_macro_name->buffer);
new_macro->parameter_list = formal_parameters;
new_macro->body = Input_skip_or_store_block(TRUE); // changes LineNumber
new_macro->body = input_skip_or_store_block(TRUE); // changes LineNumber
macro_node->body = new_macro; // link macro struct to tree node
// and that about sums it up
}
// Parse macro call ("+MACROTITLE"). Has to be re-entrant.
void Macro_parse_call(void) // Now GotByte = first char of macro name
void macro_parse_call(void) // Now GotByte = first char of macro name
{
char local_gotbyte;
struct symbol *symbol;
@ -251,7 +251,7 @@ void Macro_parse_call(void) // Now GotByte = first char of macro name
// read call-by-reference arg
dynabuf_append(internal_name, ARGTYPE_REF);
GetByte(); // eat '~'
Input_read_scope_and_symbol_name(&symbol_scope);
input_read_scope_and_symbol_name(&symbol_scope);
// GotByte = illegal char
arg_table[arg_count].symbol = symbol_find(symbol_scope); // CAUTION, object type may be NULL!
} else {
@ -260,7 +260,7 @@ void Macro_parse_call(void) // Now GotByte = first char of macro name
ALU_any_result(&(arg_table[arg_count].result));
}
++arg_count;
} while (Input_accept_comma());
} while (input_accept_comma());
}
// now arg_table contains the arguments
// now GlobalDynaBuf = unused
@ -269,7 +269,7 @@ void Macro_parse_call(void) // Now GotByte = first char of macro name
search_for_macro(&macro_node, macro_scope, FALSE);
if (macro_node == NULL) {
Throw_error("Macro not defined (or wrong signature).");
Input_skip_remainder();
input_skip_remainder();
} else {
// make macro_node point to the macro struct
actual_macro = macro_node->body;
@ -282,9 +282,9 @@ void Macro_parse_call(void) // Now GotByte = first char of macro name
new_input.state = INPUTSTATE_NORMAL; // FIXME - fix others!
new_input.src.ram_ptr = actual_macro->parameter_list;
// remember old input
outer_input = Input_now;
outer_input = input_now;
// activate new input
Input_now = &new_input;
input_now = &new_input;
outer_err_count = Throw_get_counter(); // remember error count (for call stack decision)
@ -305,15 +305,15 @@ void Macro_parse_call(void) // Now GotByte = first char of macro name
if (GotByte == REFERENCE_CHAR) {
// assign call-by-reference arg
GetByte(); // eat '~'
Input_read_scope_and_symbol_name(&symbol_scope);
input_read_scope_and_symbol_name(&symbol_scope);
// create new tree node and link existing symbol struct from arg list to it
if ((Tree_hard_scan(&symbol_node, symbols_forest, symbol_scope, TRUE) == FALSE)
if ((tree_hard_scan(&symbol_node, symbols_forest, symbol_scope, TRUE) == FALSE)
&& (FIRST_PASS))
Throw_error("Macro parameter twice.");
symbol_node->body = arg_table[arg_count].symbol; // CAUTION, object type may be NULL
} else {
// assign call-by-value arg
Input_read_scope_and_symbol_name(&symbol_scope);
input_read_scope_and_symbol_name(&symbol_scope);
symbol = symbol_find(symbol_scope);
// FIXME - find out if symbol was just created.
// Then check for the same error message here as above ("Macro parameter twice.").
@ -321,21 +321,21 @@ void Macro_parse_call(void) // Now GotByte = first char of macro name
symbol->object = arg_table[arg_count].result; // FIXME - this assignment redefines globals/whatever without throwing errors!
}
++arg_count;
} while (Input_accept_comma());
} while (input_accept_comma());
}
// and now, finally, parse the actual macro body
Input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others!
input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others!
// maybe call parse_ram_block(actual_macro->def_line_number, actual_macro->body)
Input_now->src.ram_ptr = actual_macro->body;
Parse_until_eob_or_eof();
input_now->src.ram_ptr = actual_macro->body;
parse_until_eob_or_eof();
if (GotByte != CHAR_EOB)
Bug_found("IllegalBlockTerminator", GotByte);
BUG("IllegalBlockTerminator", GotByte);
// end section (free title memory, if needed)
section_finalize(&new_section);
// restore previous section
section_now = outer_section;
// restore previous input:
Input_now = outer_input;
input_now = outer_input;
// restore old Gotbyte context
GotByte = local_gotbyte; // CAUTION - ugly kluge
@ -343,7 +343,7 @@ void Macro_parse_call(void) // Now GotByte = first char of macro name
if (Throw_get_counter() != outer_err_count)
Throw_warning("...called from here.");
Input_ensure_EOS();
input_ensure_EOS();
}
++macro_recursions_left; // leave this nesting level
}

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2016 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Macro stuff
@ -13,9 +13,10 @@
// Prototypes
// only call once (during first pass)
extern void Macro_parse_definition(void);
extern void macro_parse_definition(void);
// Parse macro call ("+MACROTITLE"). Has to be re-entrant.
extern void Macro_parse_call(void);
extern void macro_parse_call(void);
#endif

View File

@ -536,7 +536,7 @@ static struct ronode mnemo_m65_tree[] = {
// TODO: add pointer arg for result, use return value to indicate parse error!
static int get_index(void)
{
if (!Input_accept_comma())
if (!input_accept_comma())
return INDEX_NONE;
// there was a comma, so check next character (spaces will have been skipped):
@ -636,7 +636,7 @@ static bits get_addr_mode(struct number *result)
address_mode_bits |= AMB_INDEX(get_index());
}
// ensure end of line
Input_ensure_EOS();
input_ensure_EOS();
//printf("AM: %x\n", address_mode_bits);
return address_mode_bits;
}
@ -772,13 +772,13 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
// Mnemonics using only implied addressing.
static void group_only_implied_addressing(int opcode)
{
//bits force_bit = Input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
//bits force_bit = input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
// 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
if ((opcode == 0xf8) && (CPU_state.type->flags & CPUFLAG_DECIMALSUBTRACTBUGGY))
Throw_first_pass_warning("Found SED instruction for CPU with known decimal SBC bug.");
Output_byte(opcode);
Input_ensure_EOS();
output_byte(opcode);
input_ensure_EOS();
}
// helper function to output "Target not in bank" message
@ -819,10 +819,10 @@ static void near_branch(int preoffset)
}
// this fn has its own range check (see above).
// No reason to irritate the user with another error message,
// so use Output_byte() instead of output_8()
// so use output_byte() instead of output_8()
//output_8(offset);
Output_byte(offset);
Input_ensure_EOS();
output_byte(offset);
input_ensure_EOS();
}
// helper function for relative addressing with 16-bit offset
@ -844,7 +844,7 @@ static void far_branch(int preoffset)
}
}
output_le16(offset);
Input_ensure_EOS();
input_ensure_EOS();
}
// set addressing mode bits depending on which opcodes exist, then calculate
@ -861,15 +861,15 @@ static void make_instruction(bits force_bit, struct number *result, unsigned lon
addressing_modes |= MAYBE_____3;
switch (calc_arg_size(force_bit, result, addressing_modes)) {
case NUMBER_FORCES_8:
Output_byte(opcodes & 255);
output_byte(opcodes & 255);
output_8(result->val.intval);
break;
case NUMBER_FORCES_16:
Output_byte((opcodes >> 8) & 255);
output_byte((opcodes >> 8) & 255);
output_le16(result->val.intval);
break;
case NUMBER_FORCES_24:
Output_byte((opcodes >> 16) & 255);
output_byte((opcodes >> 16) & 255);
output_le24(result->val.intval);
}
}
@ -895,7 +895,7 @@ static unsigned int imm_ops(bits *force_bit, unsigned char opcode, bits immediat
long_register = CPU_state.xy_are_long;
break;
default:
Bug_found("IllegalImmediateMode", immediate_mode);
BUG("IllegalImmediateMode", immediate_mode);
}
// if the CPU does not support long registers...
if ((CPU_state.type->flags & CPUFLAG_SUPPORTSLONGREGS) == 0)
@ -923,7 +923,7 @@ static void group_main(int index, bits flags)
{
unsigned long immediate_opcodes;
struct number result;
bits force_bit = Input_get_force_bit(); // skips spaces after
bits force_bit = input_get_force_bit(); // skips spaces after
switch (get_addr_mode(&result)) {
case IMMEDIATE_ADDRESSING: // #$ff or #$ffff (depending on accu length)
@ -962,7 +962,7 @@ static void group_main(int index, bits flags)
case LONG_INDIRECT_ADDRESSING: // [$ff] for 65816 and m65
// if in quad mode, m65 encodes this as NOP + ($ff),z
if (flags & LI_PREFIX_NOP)
Output_byte(0xea);
output_byte(0xea);
make_instruction(force_bit, &result, accu_lind8[index]);
break;
case LONG_INDIRECT_Y_INDEXED_ADDRESSING: // [$ff],y only for 65816
@ -974,7 +974,7 @@ static void group_main(int index, bits flags)
case LONG_INDIRECT_Z_INDEXED_ADDRESSING: // [$ff],z only for m65
// if not in quad mode, m65 encodes this as NOP + ($ff),z
if (flags & LI_PREFIX_NOP)
Output_byte(0xea);
output_byte(0xea);
make_instruction(force_bit, &result, accu_lindz8[index]);
break;
default: // other combinations are illegal
@ -987,12 +987,12 @@ static void group_misc(int index, bits immediate_mode)
{
unsigned long immediate_opcodes;
struct number result;
bits force_bit = Input_get_force_bit(); // skips spaces after
bits force_bit = input_get_force_bit(); // skips spaces after
switch (get_addr_mode(&result)) {
case IMPLIED_ADDRESSING: // implied addressing
if (misc_impl[index])
Output_byte(misc_impl[index]);
output_byte(misc_impl[index]);
else
Throw_error(exception_illegal_combination);
break;
@ -1028,8 +1028,8 @@ static void group_misc(int index, bits immediate_mode)
// mnemonics using only 8bit relative addressing (short branch instructions).
static void group_std_branches(int opcode)
{
//bits force_bit = Input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
Output_byte(opcode);
//bits force_bit = input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
output_byte(opcode);
near_branch(2);
}
@ -1037,13 +1037,13 @@ static void group_std_branches(int opcode)
static void group_bbr_bbs(int opcode)
{
struct number zpmem;
//bits force_bit = Input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
//bits force_bit = input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
get_int_arg(&zpmem, TRUE);
typesystem_want_addr(&zpmem);
if (Input_accept_comma()) {
Output_byte(opcode);
Output_byte(zpmem.val.intval);
if (input_accept_comma()) {
output_byte(opcode);
output_byte(zpmem.val.intval);
near_branch(3);
} else {
Throw_error(exception_syntax);
@ -1053,8 +1053,8 @@ static void group_bbr_bbs(int opcode)
// mnemonics using only 16bit relative addressing (BRL and PER of 65816, and the long branches of 65ce02)
static void group_relative16(int opcode, int preoffset)
{
//bits force_bit = Input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
Output_byte(opcode);
//bits force_bit = input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
output_byte(opcode);
far_branch(preoffset);
}
@ -1065,7 +1065,7 @@ static void group_mvn_mvp(int opcode)
boolean unmatched_hash = FALSE;
struct number source,
target;
//bits force_bit = Input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
//bits force_bit = input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
// assembler syntax: "mnemonic source, target" or "mnemonic #source, #target"
// machine language order: "opcode target source"
@ -1078,7 +1078,7 @@ static void group_mvn_mvp(int opcode)
get_int_arg(&source, TRUE);
typesystem_want_nonaddr(&source);
// get comma
if (!Input_accept_comma()) {
if (!input_accept_comma()) {
Throw_error(exception_syntax);
return;
}
@ -1090,32 +1090,32 @@ static void group_mvn_mvp(int opcode)
get_int_arg(&target, TRUE);
typesystem_want_nonaddr(&target);
// output
Output_byte(opcode);
output_byte(opcode);
output_8(target.val.intval);
output_8(source.val.intval);
// sanity check
if (unmatched_hash)
Throw_error(exception_syntax);
Input_ensure_EOS();
input_ensure_EOS();
}
// "rmb0..7" and "smb0..7"
static void group_only_zp(int opcode)
{
//bits force_bit = Input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
//bits force_bit = input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
struct number target;
get_int_arg(&target, TRUE);
typesystem_want_addr(&target);
Output_byte(opcode);
output_byte(opcode);
output_8(target.val.intval);
Input_ensure_EOS();
input_ensure_EOS();
}
// NOP on m65 cpu (FIXME - "!align" outputs NOPs, what about that? what if user writes NEG:NEG?)
static void group_prefix(int opcode)
{
//bits force_bit = Input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
//bits force_bit = input_get_force_bit(); // skips spaces after // TODO - accept postfix and complain about it?
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);
@ -1126,7 +1126,7 @@ static void group_prefix(int opcode)
static void group_jump(int index)
{
struct number result;
bits force_bit = Input_get_force_bit(); // skips spaces after
bits force_bit = input_get_force_bit(); // skips spaces after
switch (get_addr_mode(&result)) {
case ABSOLUTE_ADDRESSING: // absolute16 or absolute24
@ -1159,14 +1159,14 @@ static boolean check_mnemo_tree(struct ronode *tree, struct dynabuf *dyna_buf)
bits flags;
// search for tree item
if (!Tree_easy_scan(tree, &node_body, dyna_buf))
if (!tree_easy_scan(tree, &node_body, dyna_buf))
return FALSE;
code = ((int) node_body) & CODEMASK; // get opcode or table index
flags = ((int) node_body) & FLAGSMASK; // get immediate mode flags and prefix flags
if (flags & PREFIX_NEGNEG) {
Output_byte(0x42);
Output_byte(0x42);
output_byte(0x42);
output_byte(0x42);
}
switch (GROUP((long) node_body)) {
case GROUP_ACCU: // main accumulator stuff
@ -1203,7 +1203,7 @@ static boolean check_mnemo_tree(struct ronode *tree, struct dynabuf *dyna_buf)
group_prefix(code);
break;
default: // others indicate bugs
Bug_found("IllegalGroupIndex", code);
BUG("IllegalGroupIndex", code);
}
return TRUE;
}

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// mnemonic definitions
@ -12,22 +12,31 @@
// check whether mnemonic in GlobalDynaBuf is supported by standard 6502 cpu.
extern boolean keyword_is_6502_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by NMOS 6502 cpu (includes undocumented opcodes).
extern boolean keyword_is_nmos6502_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by C64DTV2 cpu.
extern boolean keyword_is_c64dtv2_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by 65C02 cpu.
extern boolean keyword_is_65c02_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by Rockwell 65C02 cpu.
extern boolean keyword_is_r65c02_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by WDC 65C02 cpu.
extern boolean keyword_is_w65c02_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by 65816 cpu.
extern boolean keyword_is_65816_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by CSG 65CE02 cpu.
extern boolean keyword_is_65ce02_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by CSG 4502 cpu.
extern boolean keyword_is_4502_mnemo(int length);
// check whether mnemonic in GlobalDynaBuf is supported by MEGA65 cpu.
extern boolean keyword_is_m65_mnemo(int length);

View File

@ -135,7 +135,7 @@ static void border_crossed(int current_offset)
// function ptr to write byte into output buffer (might point to real fn or error trigger)
void (*Output_byte)(intval_t byte);
void (*output_byte)(intval_t byte);
// send low byte to output buffer, automatically increasing program counter
@ -165,14 +165,14 @@ static void no_output(intval_t byte)
{
Throw_error(exception_pc_undefined);
// now change fn ptr to not complain again.
Output_byte = real_output;
Output_byte(byte); // try again
output_byte = real_output;
output_byte(byte); // try again
}
// skip over some bytes in output buffer without starting a new segment
// (used by "!skip", and also called by "!binary" if really calling
// Output_byte would be a waste of time)
// output_byte would be a waste of time)
void output_skip(int size)
{
if (size < 1) {
@ -182,8 +182,8 @@ void output_skip(int size)
}
// check whether ptr undefined
if (Output_byte == no_output) {
Output_byte(0); // trigger error with a dummy byte
if (output_byte == no_output) {
output_byte(0); // trigger error with a dummy byte
--size; // fix amount to cater for dummy byte
}
// CAUTION - there are two copies of these checks!
@ -212,7 +212,7 @@ static void fill_completely(char value)
// define default value for empty memory ("!initmem" pseudo opcode)
// returns zero if ok, nonzero if already set
int output_initmem(char content)
int output_setdefault(char content)
{
// if MemInit flag is already set, complain
if (out->initvalue_set) {
@ -241,7 +241,7 @@ int outputfile_set_format(void)
void *node_body;
// perform lookup
if (!Tree_easy_scan(file_format_tree, &node_body, GlobalDynaBuf))
if (!tree_easy_scan(file_format_tree, &node_body, GlobalDynaBuf))
return 1;
output_format = (enum output_format) node_body;
@ -276,7 +276,7 @@ int outputfile_set_filename(void)
// init output struct (done later)
void Output_init(signed long fill_value, boolean use_large_buf)
void output_createbuffer(signed long fill_value, boolean use_large_buf)
{
out->bufsize = use_large_buf ? 0x1000000 : 0x10000;
out->buffer = safe_malloc(out->bufsize);
@ -295,7 +295,7 @@ void Output_init(signed long fill_value, boolean use_large_buf)
// dump used portion of output buffer into output file
void Output_save_file(FILE *fd)
void output_save_file(FILE *fd)
{
intval_t start,
amount;
@ -388,7 +388,7 @@ static void check_segment(intval_t new_pc)
// clear segment list and disable output
void Output_passinit(void)
void output_passinit(void)
{
// struct segment *temp;
@ -405,7 +405,7 @@ void Output_passinit(void)
out->lowest_written = out->bufsize - 1;
out->highest_written = 0;
// deactivate output - any byte written will trigger error:
Output_byte = no_output;
output_byte = no_output;
out->write_idx = 0; // same as pc on pass init!
out->segment.start = NO_SEGMENT_START; // TODO - "no active segment" could be made a segment flag!
out->segment.max = out->bufsize - 1; // TODO - use end of bank?
@ -427,7 +427,7 @@ void Output_passinit(void)
// show start and end of current segment
// called whenever a new segment begins, and at end of pass.
void Output_end_segment(void)
void output_end_segment(void)
{
intval_t amount;
@ -461,17 +461,17 @@ void Output_end_segment(void)
// change output pointer and enable output
// TODO - this only gets called from vcpu_set_pc so could be made static!
void Output_start_segment(intval_t address_change, bits segment_flags)
void output_start_segment(intval_t address_change, bits segment_flags)
{
// properly finalize previous segment (link to list, announce)
Output_end_segment();
output_end_segment();
// calculate start of new segment
out->write_idx = (out->write_idx + address_change) & (out->bufsize - 1);
out->segment.start = out->write_idx;
out->segment.flags = segment_flags;
// allow writing to output buffer
Output_byte = real_output;
output_byte = real_output;
// in first pass, check for other segments and maybe issue warning
// TODO - remove FIRST_PASS condition
if (FIRST_PASS) {
@ -486,6 +486,7 @@ char output_get_xor(void)
{
return out->xor;
}
void output_set_xor(char xor)
{
out->xor = xor;
@ -518,7 +519,7 @@ void vcpu_set_pc(intval_t new_pc, bits segment_flags)
CPU_state.pc.ntype = NUMTYPE_INT; // FIXME - remove when allowing undefined!
CPU_state.pc.addr_refs = 1; // yes, PC counts as address
// now tell output buffer to start a new segment
Output_start_segment(pc_change, segment_flags);
output_start_segment(pc_change, segment_flags);
}
/*
TODO - overhaul program counter and memory pointer stuff:
@ -604,7 +605,7 @@ void pseudopc_end(void)
// encountering "*=".
// so if wanted version is new enough, choke on bug!
if (config.wanted_version >= VER_DISABLED_OBSOLETE_STUFF)
Bug_found("ClosingUnopenedPseudopcBlock", 0);
BUG("ClosingUnopenedPseudopcBlock", 0);
} else {
CPU_state.pc.val.intval = (CPU_state.pc.val.intval - pseudopc_current_context->offset) & (out->bufsize - 1); // pc might have wrapped around
CPU_state.pc.ntype = pseudopc_current_context->ntype;

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Output stuff (FIXME - split into outbuf, outfile/format and vcpu parts)
@ -37,61 +37,83 @@ extern struct vcpu CPU_state; // current CPU state FIXME - restrict visibility t
// clear segment list and disable output
//TODO - does this belong to outbuf stuff?
extern void Output_passinit(void);
extern void output_passinit(void);
// outbuf stuff:
// alloc and init mem buffer (done later)
extern void Output_init(signed long fill_value, boolean use_large_buf);
extern void output_createbuffer(signed long fill_value, boolean use_large_buf);
// skip over some bytes in output buffer without starting a new segment
// (used by "!skip", and also called by "!binary" if really calling
// Output_byte would be a waste of time)
// output_byte would be a waste of time)
extern void output_skip(int size);
// Send low byte of arg to output buffer and advance pointer
// FIXME - replace by output_sequence(char *src, size_t size)
extern void (*Output_byte)(intval_t);
extern void (*output_byte)(intval_t);
// define default value for empty memory ("!initmem" pseudo opcode)
// returns zero if ok, nonzero if already set
extern int output_initmem(char content);
extern int output_setdefault(char content);
// outfile stuff:
// try to set output format held in DynaBuf. Returns zero on success.
extern int outputfile_set_format(void);
extern const char outputfile_formats[]; // string to show if outputfile_set_format() returns nonzero
// if file format was already chosen, returns zero.
// if file format isn't set, chooses CBM and returns 1.
extern int outputfile_prefer_cbm_format(void);
// try to set output file name held in DynaBuf. Returns zero on success.
extern int outputfile_set_filename(void);
// write smallest-possible part of memory buffer to file
extern void Output_save_file(FILE *fd);
extern void output_save_file(FILE *fd);
// change output pointer and enable output
extern void Output_start_segment(intval_t address_change, bits segment_flags);
extern void output_start_segment(intval_t address_change, bits segment_flags);
// Show start and end of current segment
extern void Output_end_segment(void);
extern void output_end_segment(void);
extern char output_get_xor(void);
extern void output_set_xor(char xor);
// set program counter to defined value (TODO - allow undefined!)
extern void vcpu_set_pc(intval_t new_pc, bits flags);
// get program counter
extern void vcpu_read_pc(struct number *target);
// get size of current statement (until now) - needed for "!bin" verbose output
extern int vcpu_get_statement_size(void);
// adjust program counter (called at end of each statement)
extern void vcpu_end_statement(void);
// pseudopc stuff:
struct pseudopc;
// start offset assembly
extern void pseudopc_start(struct number *new_pc);
// end offset assembly
extern void pseudopc_end(void);
// this is only for old, deprecated, obsolete, stupid "realpc":
extern void pseudopc_end_all(void);
// un-pseudopc a label value by given number of levels
// returns nonzero on error (if level too high)
extern int pseudopc_unpseudo(struct number *target, struct pseudopc *context, unsigned int levels);
// return pointer to current "pseudopc" struct (may be NULL!)
// this gets called when parsing label definitions
extern struct pseudopc *pseudopc_get_context(void);

View File

@ -52,9 +52,9 @@ void notreallypo_setpc(void) // GotByte is '*'
GetByte();
ALU_defined_int(&intresult); // read new address
// check for modifiers
while (Input_accept_comma()) {
while (input_accept_comma()) {
// parse modifier. if no keyword given, give up
if (Input_read_and_lower_keyword() == 0)
if (input_read_and_lower_keyword() == 0)
goto fail;
if (strcmp(GlobalDynaBuf->buffer, "overlay") == 0) {
@ -78,11 +78,11 @@ void notreallypo_setpc(void) // GotByte is '*'
}
vcpu_set_pc(intresult.val.intval, segment_flags);
// TODO - allow block syntax, so it is possible to put data "somewhere else" and then return to old position?
Input_ensure_EOS();
input_ensure_EOS();
return;
fail:
Input_skip_remainder();
input_skip_remainder();
}
@ -99,7 +99,7 @@ static enum eos po_initmem(void)
ALU_defined_int(&intresult);
if ((intresult.val.intval > 255) || (intresult.val.intval < -128))
Throw_error(exception_number_out_of_8b_range);
if (output_initmem(intresult.val.intval & 0xff))
if (output_setdefault(intresult.val.intval & 0xff))
return SKIP_REMAINDER;
return ENSURE_EOS;
}
@ -120,7 +120,7 @@ static enum eos po_xor(void)
}
output_set_xor(old_value ^ change);
// if there's a block, parse that and then restore old value!
if (Parse_optional_block())
if (parse_optional_block())
output_set_xor(old_value);
return ENSURE_EOS;
}
@ -136,7 +136,7 @@ static enum eos po_to(void)
// read filename to global dynamic buffer
// if no file name given, exit (complaining will have been done)
if (Input_read_filename(FALSE, NULL))
if (input_read_filename(FALSE, NULL))
return SKIP_REMAINDER;
// only act upon this pseudo opcode in first pass
@ -148,7 +148,7 @@ static enum eos po_to(void)
// select output format
// if no comma found, use default file format
if (Input_accept_comma() == FALSE) {
if (input_accept_comma() == FALSE) {
if (outputfile_prefer_cbm_format()) {
// output deprecation warning (unless user requests really old behaviour)
if (config.wanted_version >= VER_DEPRECATE_REALPC)
@ -159,7 +159,7 @@ static enum eos po_to(void)
// parse output format name
// if no keyword given, give up
if (Input_read_and_lower_keyword() == 0)
if (input_read_and_lower_keyword() == 0)
return SKIP_REMAINDER;
if (outputfile_set_format()) {
@ -183,7 +183,7 @@ static enum eos iterate(void (*fn)(intval_t))
do {
ALU_any_result(&object);
output_object(&object, &iter);
} while (Input_accept_comma());
} while (input_accept_comma());
return ENSURE_EOS;
}
@ -254,7 +254,7 @@ static enum eos po_hex(void) // now GotByte = illegal char
for (;;) {
if (digits == 2) {
Output_byte(byte);
output_byte(byte);
digits = 0;
byte = 0;
}
@ -324,7 +324,7 @@ static enum eos user_defined_encoding(FILE *stream)
encoder_current = &encoder_file; // activate new encoding
encoding_loaded_table = local_table; // activate local table
// if there's a block, parse that and then restore old values
if (Parse_optional_block()) {
if (parse_optional_block()) {
encoder_current = buffered_encoder;
} else {
// if there's *no* block, the table must be used from now on.
@ -344,7 +344,7 @@ static enum eos predefined_encoding(void)
*buffered_table = encoding_loaded_table;
const struct encoder *buffered_encoder = encoder_current;
if (Input_read_and_lower_keyword()) {
if (input_read_and_lower_keyword()) {
const struct encoder *new_encoder = encoding_find();
if (new_encoder)
@ -352,7 +352,7 @@ static enum eos predefined_encoding(void)
}
encoding_loaded_table = local_table; // activate local table
// if there's a block, parse that and then restore old values
if (Parse_optional_block())
if (parse_optional_block())
encoder_current = buffered_encoder;
// re-activate "outer" table
encoding_loaded_table = buffered_table;
@ -367,7 +367,7 @@ static enum eos po_convtab(void)
if ((GotByte == '<') || (GotByte == '"')) {
// encoding table from file
if (Input_read_filename(TRUE, &uses_lib))
if (input_read_filename(TRUE, &uses_lib))
return SKIP_REMAINDER; // missing or unterminated file name
stream = includepaths_open_ro(uses_lib);
@ -397,13 +397,13 @@ static enum eos encode_string(const struct encoder *inner_encoder, unsigned char
int offset;
dynabuf_clear(GlobalDynaBuf);
if (Input_quoted_to_dynabuf('"'))
if (input_quoted_to_dynabuf('"'))
return SKIP_REMAINDER; // unterminated or escaping error
// eat closing quote
GetByte();
// now convert to unescaped version
if (Input_unescape_dynabuf(0))
if (input_unescape_dynabuf(0))
return SKIP_REMAINDER; // escaping error
// send characters
@ -416,7 +416,7 @@ static enum eos encode_string(const struct encoder *inner_encoder, unsigned char
ALU_any_result(&object);
output_object(&object, &iter);
}
} while (Input_accept_comma());
} while (input_accept_comma());
encoder_current = outer_encoder; // reactivate buffered encoder
return ENSURE_EOS;
}
@ -446,7 +446,7 @@ static enum eos po_scrxor(void)
intval_t xor;
ALU_any_int(&xor);
if (Input_accept_comma() == FALSE) {
if (input_accept_comma() == FALSE) {
Throw_error(exception_syntax);
return SKIP_REMAINDER;
}
@ -467,7 +467,7 @@ static enum eos po_binary(void)
skip.val.intval = 0;
// if file name is missing, don't bother continuing
if (Input_read_filename(TRUE, &uses_lib))
if (input_read_filename(TRUE, &uses_lib))
return SKIP_REMAINDER;
// try to open file
@ -476,7 +476,7 @@ static enum eos po_binary(void)
return SKIP_REMAINDER;
// read optional arguments
if (Input_accept_comma()) {
if (input_accept_comma()) {
// any size given?
if ((GotByte != ',') && (GotByte != CHAR_EOS)) {
// then parse it
@ -485,7 +485,7 @@ static enum eos po_binary(void)
Throw_serious_error(exception_negative_size);
}
// more?
if (Input_accept_comma()) {
if (input_accept_comma()) {
// any skip given?
if (GotByte != CHAR_EOS) {
// then parse it
@ -508,15 +508,15 @@ static enum eos po_binary(void)
byte = getc(stream);
if (byte == EOF)
break;
Output_byte(byte);
output_byte(byte);
--size.val.intval;
}
// if more should have been read, warn and add padding
if (size.val.intval > 0) {
Throw_warning("Padding with zeroes.");
do
Output_byte(0);
while (--size.val.intval);
do {
output_byte(0);
} while (--size.val.intval);
}
}
fclose(stream);
@ -538,7 +538,7 @@ static enum eos po_fill(void)
intval_t fill = FILLVALUE_FILL;
ALU_defined_int(&sizeresult); // FIXME - forbid addresses!
if (Input_accept_comma())
if (input_accept_comma())
ALU_any_int(&fill); // FIXME - forbid addresses!
while (sizeresult.val.intval--)
output_8(fill);
@ -575,10 +575,10 @@ static enum eos po_align(void)
// new: !align BLOCKSIZE
// ...where block size must be a power of two
ALU_defined_int(&andresult); // FIXME - forbid addresses!
if (!Input_accept_comma())
if (!input_accept_comma())
Throw_error(exception_syntax);
ALU_defined_int(&equalresult); // ...allow addresses (unlikely, but possible)
if (Input_accept_comma())
if (input_accept_comma())
ALU_any_int(&fill);
else
fill = CPU_state.type->default_align_value;
@ -624,9 +624,9 @@ static enum eos po_pseudopc(void)
ALU_defined_int(&new_pc); // FIXME - allow for undefined! (complaining about non-addresses would be logical, but annoying)
/* TODO - add this. check if code can be shared with "*="!
// check for modifiers
while (Input_accept_comma()) {
while (input_accept_comma()) {
// parse modifier. if no keyword given, give up
if (Input_read_and_lower_keyword() == 0)
if (input_read_and_lower_keyword() == 0)
return SKIP_REMAINDER;
if (strcmp(GlobalDynaBuf->buffer, "limit") == 0) {
@ -643,7 +643,7 @@ static enum eos po_pseudopc(void)
*/
pseudopc_start(&new_pc);
// if there's a block, parse that and then restore old value!
if (Parse_optional_block()) {
if (parse_optional_block()) {
pseudopc_end(); // restore old state
} else {
old_offset_assembly();
@ -668,7 +668,7 @@ static enum eos po_cpu(void)
const struct cpu_type *cpu_buffer = CPU_state.type; // remember current cpu
const struct cpu_type *new_cpu_type;
if (Input_read_and_lower_keyword()) {
if (input_read_and_lower_keyword()) {
new_cpu_type = cputype_find();
if (new_cpu_type)
CPU_state.type = new_cpu_type; // activate new cpu type
@ -676,7 +676,7 @@ static enum eos po_cpu(void)
Throw_error("Unknown processor.");
}
// if there's a block, parse that and then restore old value
if (Parse_optional_block())
if (parse_optional_block())
CPU_state.type = cpu_buffer;
return ENSURE_EOS;
}
@ -691,7 +691,7 @@ static enum eos set_register_length(boolean *var, boolean make_long)
// set new register length (or complain - whichever is more fitting)
vcpu_check_and_set_reg_length(var, make_long);
// if there's a block, parse that and then restore old value!
if (Parse_optional_block())
if (parse_optional_block())
vcpu_check_and_set_reg_length(var, old_size); // restore old length
return ENSURE_EOS;
}
@ -750,10 +750,10 @@ static enum eos po_set(void) // now GotByte = illegal char
scope_t scope;
int force_bit;
if (Input_read_scope_and_symbol_name(&scope)) // skips spaces before
if (input_read_scope_and_symbol_name(&scope)) // skips spaces before
return SKIP_REMAINDER; // zero length
force_bit = Input_get_force_bit(); // skips spaces after
force_bit = input_get_force_bit(); // skips spaces after
if (GotByte != '=') {
Throw_error(exception_syntax);
return SKIP_REMAINDER;
@ -780,7 +780,7 @@ static enum eos po_symbollist(void)
// read filename to global dynamic buffer
// if no file name given, exit (complaining will have been done)
if (Input_read_filename(FALSE, NULL))
if (input_read_filename(FALSE, NULL))
return SKIP_REMAINDER;
// only process this pseudo opcode in first pass
@ -818,14 +818,14 @@ static enum eos po_zone(void)
if (BYTE_CONTINUES_KEYWORD(GotByte)) {
// because we know of one character for sure,
// there's no need to check the return value.
Input_read_keyword();
input_read_keyword();
new_title = dynabuf_get_copy(GlobalDynaBuf);
allocated = TRUE;
}
// setup new section
// section type is "subzone", just in case a block follows
section_new(section_now, "Subzone", new_title, allocated);
if (Parse_optional_block()) {
if (parse_optional_block()) {
// block has been parsed, so it was a SUBzone.
section_finalize(section_now); // end inner zone
*section_now = entry_values; // restore entry values
@ -862,7 +862,7 @@ static enum eos po_source(void) // now GotByte = illegal char
if (--source_recursions_left < 0)
Throw_serious_error("Too deeply nested. Recursive \"!source\"?");
// read file name. quit function on error
if (Input_read_filename(TRUE, &uses_lib))
if (input_read_filename(TRUE, &uses_lib))
return SKIP_REMAINDER;
// if file could be opened, parse it. otherwise, complain
@ -876,11 +876,11 @@ static enum eos po_source(void) // now GotByte = illegal char
#endif
strcpy(filename, GLOBALDYNABUF_CURRENT);
outer_input = Input_now; // remember old input
outer_input = input_now; // remember old input
local_gotbyte = GotByte; // CAUTION - ugly kluge
Input_now = &new_input; // activate new input
input_now = &new_input; // activate new input
flow_parse_and_close_file(stream, filename);
Input_now = outer_input; // restore previous input
input_now = outer_input; // restore previous input
GotByte = local_gotbyte; // CAUTION - ugly kluge
#ifndef __GNUC__
free(filename); // GCC auto-frees
@ -924,7 +924,7 @@ static enum eos ifelse(enum ifmode mode)
condition_met = TRUE;
break;
default:
Bug_found("IllegalIfMode", mode);
BUG("IllegalIfMode", mode);
condition_met = TRUE; // inhibit compiler warning ;)
}
SKIPSPACE();
@ -932,7 +932,7 @@ static enum eos ifelse(enum ifmode mode)
if (condition_met && nothing_done) {
nothing_done = FALSE; // all further ones will be skipped, even if conditions meet
if (GotByte == CHAR_SOB) {
Parse_until_eob_or_eof(); // parse block
parse_until_eob_or_eof(); // parse block
// if block isn't correctly terminated, complain and exit
if (GotByte != CHAR_EOB)
Throw_serious_error(exception_no_right_brace);
@ -941,7 +941,7 @@ static enum eos ifelse(enum ifmode mode)
}
} else {
if (GotByte == CHAR_SOB) {
Input_skip_or_store_block(FALSE); // skip block
input_skip_or_store_block(FALSE); // skip block
} else {
return SKIP_REMAINDER; // skip line (only for ifdef/ifndef)
}
@ -961,7 +961,7 @@ static enum eos ifelse(enum ifmode mode)
return AT_EOS_ANYWAY; // normal exit if there is no ELSE {...} block
// read keyword (expected to be "else")
if (Input_read_and_lower_keyword() == 0)
if (input_read_and_lower_keyword() == 0)
return SKIP_REMAINDER; // "missing string error" -> ignore rest of line
// make sure it's "else"
@ -978,7 +978,7 @@ static enum eos ifelse(enum ifmode mode)
}
// read keyword (expected to be if/ifdef/ifndef)
if (Input_read_and_lower_keyword() == 0)
if (input_read_and_lower_keyword() == 0)
return SKIP_REMAINDER; // "missing string error" -> ignore rest of line
// which one is it?
@ -1027,18 +1027,18 @@ static enum eos po_for(void) // now GotByte = illegal char
struct for_loop loop;
struct number intresult;
if (Input_read_scope_and_symbol_name(&scope)) // skips spaces before
if (input_read_scope_and_symbol_name(&scope)) // skips spaces before
return SKIP_REMAINDER; // zero length
// now GotByte = illegal char
force_bit = Input_get_force_bit(); // skips spaces after
force_bit = input_get_force_bit(); // skips spaces after
loop.symbol = symbol_find(scope); // if not number, error will be reported on first assignment
if (Input_accept_comma()) {
if (input_accept_comma()) {
// counter syntax (old or new)
loop.u.counter.force_bit = force_bit;
ALU_defined_int(&intresult); // read first argument
loop.u.counter.addr_refs = intresult.addr_refs;
if (Input_accept_comma()) {
if (input_accept_comma()) {
// new counter syntax
loop.algorithm = FORALGO_NEWCOUNT;
if (config.wanted_version < VER_NEWFORSYNTAX)
@ -1086,9 +1086,9 @@ 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
user if they did not even want to put a string there.
so if the current byte is not the start of "in" we just throw a syntax error.
knowing there is an "i" also makes sure that Input_read_and_lower_keyword()
knowing there is an "i" also makes sure that input_read_and_lower_keyword()
does not fail. */
Input_read_and_lower_keyword();
input_read_and_lower_keyword();
if (strcmp(GlobalDynaBuf->buffer, "in") != 0) {
Throw_error("Loop var must be followed by either \"in\" keyword or comma.");
return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}'
@ -1109,9 +1109,9 @@ does not fail. */
Throw_serious_error(exception_no_left_brace);
// remember line number of loop pseudo opcode
loop.block.start = Input_now->line_number;
loop.block.start = input_now->line_number;
// read loop body into DynaBuf and get copy
loop.block.body = Input_skip_or_store_block(TRUE); // changes line number!
loop.block.body = input_skip_or_store_block(TRUE); // changes line number!
flow_forloop(&loop);
// free memory
@ -1135,9 +1135,9 @@ static enum eos po_do(void) // now GotByte = illegal char
Throw_serious_error(exception_no_left_brace);
// remember line number of loop body,
// then read block and get copy
loop.block.start = Input_now->line_number;
loop.block.start = input_now->line_number;
// reading block changes line number!
loop.block.body = Input_skip_or_store_block(TRUE); // must be freed!
loop.block.body = input_skip_or_store_block(TRUE); // must be freed!
// now GotByte = '}'
NEXTANDSKIPSPACE(); // now GotByte = first non-blank char after block
// read tail condition to buffer
@ -1164,9 +1164,9 @@ static enum eos po_while(void) // now GotByte = illegal char
Throw_serious_error(exception_no_left_brace);
// remember line number of loop body,
// then read block and get copy
loop.block.start = Input_now->line_number;
loop.block.start = input_now->line_number;
// reading block changes line number!
loop.block.body = Input_skip_or_store_block(TRUE); // must be freed!
loop.block.body = input_skip_or_store_block(TRUE); // must be freed!
// clear tail condition
loop.tail_cond.body = NULL;
flow_do_while(&loop);
@ -1184,7 +1184,7 @@ static enum eos po_macro(void) // now GotByte = illegal char
{
// in first pass, parse. In all other passes, skip.
if (FIRST_PASS) {
Macro_parse_definition(); // now GotByte = '}'
macro_parse_definition(); // now GotByte = '}'
} else {
// skip until CHAR_SOB ('{') is found.
// no need to check for end-of-statement, because such an
@ -1192,7 +1192,7 @@ static enum eos po_macro(void) // now GotByte = illegal char
// for the same reason, there is no need to check for quotes.
while (GotByte != CHAR_SOB)
GetByte();
Input_skip_or_store_block(FALSE); // now GotByte = '}'
input_skip_or_store_block(FALSE); // now GotByte = '}'
}
GetByte(); // Proceed with next character
return ENSURE_EOS;
@ -1216,7 +1216,7 @@ static enum eos tracewatch(boolean enter_monitor)
if (GotByte != CHAR_EOS) {
do {
// parse flag. if no keyword given, give up
if (Input_read_and_lower_keyword() == 0)
if (input_read_and_lower_keyword() == 0)
return SKIP_REMAINDER; // fail (error has been reported)
if (strcmp(GlobalDynaBuf->buffer, "load") == 0) {
@ -1229,7 +1229,7 @@ static enum eos tracewatch(boolean enter_monitor)
Throw_error("Unknown flag (known are: load, store, exec)."); // FIXME - add to docs!
return SKIP_REMAINDER;
}
} while (Input_accept_comma());
} while (input_accept_comma());
}
// shortcut: no flags at all -> set all flags!
if (!flags)
@ -1260,7 +1260,7 @@ static enum eos po_nowarn(void)
global_inhibit_warnings = TRUE;
// if there's a block, parse it and then restore old value
if (Parse_optional_block()) {
if (parse_optional_block()) {
global_inhibit_warnings = flag_buf;
return ENSURE_EOS;
} else {
@ -1289,13 +1289,13 @@ static enum eos throw_string(const char prefix[], void (*fn)(const char *))
do {
if ((GotByte == '"') && (config.wanted_version < VER_BACKSLASHESCAPING)) {
dynabuf_clear(GlobalDynaBuf);
if (Input_quoted_to_dynabuf('"'))
if (input_quoted_to_dynabuf('"'))
return SKIP_REMAINDER; // unterminated or escaping error
// eat closing quote
GetByte();
// now convert to unescaped version
if (Input_unescape_dynabuf(0))
if (input_unescape_dynabuf(0))
return SKIP_REMAINDER; // escaping error
dynabuf_append(GlobalDynaBuf, '\0'); // terminate string
@ -1305,7 +1305,7 @@ static enum eos throw_string(const char prefix[], void (*fn)(const char *))
ALU_any_result(&object);
object.type->print(&object, user_message);
}
} while (Input_accept_comma());
} while (input_accept_comma());
dynabuf_append(user_message, '\0');
fn(user_message->buffer);
return ENSURE_EOS;
@ -1353,8 +1353,8 @@ static enum eos po_serious(void)
static enum eos po_endoffile(void)
{
// well, it doesn't end right here and now, but at end-of-line! :-)
Input_ensure_EOS();
Input_now->state = INPUTSTATE_EOF;
input_ensure_EOS();
input_now->state = INPUTSTATE_EOF;
return AT_EOS_ANYWAY;
}
@ -1447,9 +1447,9 @@ void pseudoopcode_parse(void) // now GotByte = "!"
GetByte(); // read next byte
// on missing keyword, return (complaining will have been done)
if (Input_read_and_lower_keyword()) {
if (input_read_and_lower_keyword()) {
// search for tree item
if ((Tree_easy_scan(pseudo_opcode_tree, &node_body, GlobalDynaBuf))
if ((tree_easy_scan(pseudo_opcode_tree, &node_body, GlobalDynaBuf))
&& node_body) {
fn = (enum eos (*)(void)) node_body;
SKIPSPACE();
@ -1460,9 +1460,9 @@ void pseudoopcode_parse(void) // now GotByte = "!"
}
}
if (then == SKIP_REMAINDER)
Input_skip_remainder();
input_skip_remainder();
else if (then == ENSURE_EOS)
Input_ensure_EOS();
input_ensure_EOS();
// the other two possibilities (PARSE_REMAINDER and AT_EOS_ANYWAY)
// will lead to the remainder of the line being parsed by the mainloop.
}

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// pseudo opcode stuff
@ -9,6 +9,7 @@
// call when "*= EXPRESSION" is parsed
extern void notreallypo_setpc(void);
// parse pseudo opcode. has to be re-entrant.
extern void pseudoopcode_parse(void);

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// section stuff
@ -26,10 +26,13 @@ extern struct section *section_now;
// write given info into given structure and activate it
extern void section_new(struct section *section, const char *type, char *title, boolean allocated);
// change scope of cheap locals in given section
extern void section_new_cheap_scope(struct section *section);
// setup outermost section
extern void section_passinit(void);
// tidy up: if necessary, release section title.
extern void section_finalize(struct section *section);

View File

@ -60,7 +60,7 @@ static void dump_one_symbol(struct rwnode *node, FILE *fd)
else if (symbol->object.u.number.ntype == NUMTYPE_FLOAT)
fprintf(fd, "%.30f", symbol->object.u.number.val.fpval); //FIXME %g
else
Bug_found("IllegalNumberType4", symbol->object.u.number.ntype);
BUG("IllegalNumberType4", symbol->object.u.number.ntype);
if (symbol->object.u.number.flags & NUMBER_EVER_UNDEFINED)
fprintf(fd, "\t; ?"); // TODO - write "forward" instead?
if (!symbol->has_been_read)
@ -112,7 +112,7 @@ struct symbol *symbol_find(scope_t scope)
struct symbol *symbol;
boolean node_created;
node_created = Tree_hard_scan(&node, symbols_forest, scope, TRUE);
node_created = tree_hard_scan(&node, symbols_forest, scope, TRUE);
// if node has just been created, create symbol as well
if (node_created) {
// create new symbol structure
@ -175,9 +175,9 @@ void symbol_set_object(struct symbol *symbol, struct object *new_value, bits pow
void symbol_set_force_bit(struct symbol *symbol, bits force_bit)
{
if (!force_bit)
Bug_found("ForceBitZero", 0);
BUG("ForceBitZero", 0);
if (symbol->object.type == NULL)
Bug_found("NullTypeObject", 0);
BUG("NullTypeObject", 0);
if (symbol->object.type != &type_number) {
Throw_error("Force bits can only be given to numbers.");
@ -216,7 +216,7 @@ void symbol_define(intval_t value)
// dump global symbols to file
void symbols_list(FILE *fd)
{
Tree_dump_forest(symbols_forest, SCOPE_GLOBAL, dump_one_symbol, fd);
tree_dump_forest(symbols_forest, SCOPE_GLOBAL, dump_one_symbol, fd);
}
@ -225,13 +225,13 @@ void symbols_vicelabels(FILE *fd)
// FIXME - if type checking is enabled, maybe only output addresses?
// the order of dumped labels is important because VICE will prefer later defined labels
// dump unused labels
Tree_dump_forest(symbols_forest, SCOPE_GLOBAL, dump_vice_unusednonaddress, fd);
tree_dump_forest(symbols_forest, SCOPE_GLOBAL, dump_vice_unusednonaddress, fd);
fputc('\n', fd);
// dump other used labels
Tree_dump_forest(symbols_forest, SCOPE_GLOBAL, dump_vice_usednonaddress, fd);
tree_dump_forest(symbols_forest, SCOPE_GLOBAL, dump_vice_usednonaddress, fd);
fputc('\n', fd);
// dump address symbols
Tree_dump_forest(symbols_forest, SCOPE_GLOBAL, dump_vice_address, fd);
tree_dump_forest(symbols_forest, SCOPE_GLOBAL, dump_vice_address, fd);
// TODO - add trace points and watch points with load/store/exec args!
}
@ -263,7 +263,7 @@ void symbol_fix_forward_anon_name(boolean increment)
counter_symbol->object.u.number.val.intval = 0;
} else if (counter_symbol->object.type != &type_number) {
// sanity check: it must be a number!
Bug_found("ForwardAnonCounterNotInt", 0);
BUG("ForwardAnonCounterNotInt", 0);
}
// make sure it gets reset to zero in each new pass
if (counter_symbol->pass != pass.number) {
@ -300,7 +300,7 @@ int symbol_fix_dynamic_name(void)
boolean parenthesized;
if (GotByte != '?')
Bug_found("NotQuestionMark", GotByte);
BUG("NotQuestionMark", GotByte);
// start with base name
// (reading the inner parts will clobber GlobalDynaBuf, so copy it now)
@ -318,7 +318,7 @@ int symbol_fix_dynamic_name(void)
}
// read inner part
if (Input_read_scope_and_symbol_name(&tmp_scope))
if (input_read_scope_and_symbol_name(&tmp_scope))
return 1;
tmp_symbol = symbol_find(tmp_scope);

View File

@ -65,7 +65,7 @@ static void tree_from_list(struct ronode **tree, struct ronode *table_to_add)
// tree item that matches the given data (HashValue and DynaBuf-String).
// Store "body" component in node_body and return TRUE.
// Return FALSE if no matching item found.
int Tree_easy_scan(struct ronode *tree, void **node_body, struct dynabuf *dyna_buf)
int tree_easy_scan(struct ronode *tree, void **node_body, struct dynabuf *dyna_buf)
{
struct ronode wanted; // temporary storage
const char *p1,
@ -121,7 +121,7 @@ int Tree_easy_scan(struct ronode *tree, void **node_body, struct dynabuf *dyna_b
// a new tree item, link to tree, fill with data and store its pointer. If the
// "create" flag is zero, store NULL as result.
// Returns whether item was created.
int Tree_hard_scan(struct rwnode **result, struct rwnode **forest, int id_number, boolean create)
int tree_hard_scan(struct rwnode **result, struct rwnode **forest, int id_number, boolean create)
{
struct ronode wanted; // temporary storage
struct rwnode **current_node;
@ -200,8 +200,8 @@ static void dump_tree(struct rwnode *node, int id_number, void (*fn)(struct rwno
dump_tree(node->less_than_or_equal, id_number, fn, env);
}
// Call Tree_dump_tree for each non-zero entry of the given tree table.
void Tree_dump_forest(struct rwnode **forest, int id_number, void (*fn)(struct rwnode *, FILE *), FILE *env)
// call dump_tree for each non-zero entry of the given tree table.
void tree_dump_forest(struct rwnode **forest, int id_number, void (*fn)(struct rwnode *, FILE *), FILE *env)
{
int ii;

View File

@ -45,16 +45,16 @@ struct rwnode {
// Search for a given ID string in a given tree. Store "body" component in
// node_body and return TRUE. Return FALSE if no matching item found.
struct dynabuf;
extern int Tree_easy_scan(struct ronode *tree, void **node_body, struct dynabuf *dyna_buf);
extern int tree_easy_scan(struct ronode *tree, void **node_body, struct dynabuf *dyna_buf);
// Search for a "RAM tree" item. Save pointer to found tree item in given
// location. If no matching item is found, check the "create" flag: If set,
// create new tree item, link to tree, fill with data and store its pointer.
// If "create" is FALSE, store NULL. Returns whether item was created.
extern int Tree_hard_scan(struct rwnode **result, struct rwnode **forest, int id_number, boolean create);
extern int tree_hard_scan(struct rwnode **result, struct rwnode **forest, int id_number, boolean create);
// Call given function for each node of each tree of given forest.
extern void Tree_dump_forest(struct rwnode **, int id_number, void (*)(struct rwnode *, FILE *), FILE *);
extern void tree_dump_forest(struct rwnode **, int id_number, void (*)(struct rwnode *, FILE *), FILE *);
#endif

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// type system stuff
@ -26,7 +26,7 @@ void typesystem_force_address_block(void)
boolean buffer = in_address_block;
in_address_block = TRUE;
Parse_optional_block();
parse_optional_block();
in_address_block = buffer;
}

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Type system stuff
@ -12,12 +12,16 @@
// return whether explicit symbol definitions should force "address" mode
extern boolean typesystem_says_address(void);
// parse a block while forcing address mode
extern void typesystem_force_address_block(void);
// force address mode on or off for the next statement
extern void typesystem_force_address_statement(boolean value);
// warn if result is not integer
extern void typesystem_want_nonaddr(struct number *result);
// warn if result is not address
extern void typesystem_want_addr(struct number *result);

View File

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