added experimental feature to dynamically create symbol names (and a bit of cleanup)

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@328 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-01-29 22:02:28 +00:00
parent b9d7e83e5c
commit aec6f8e99d
17 changed files with 215 additions and 141 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 DOS, OS/2 and Windows)
@ -24,12 +24,12 @@ void DOS_entry(void)
env_var = getenv("ACME");
// if environment variable was found, make a copy
if (env_var) {
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
// copy environment variable to global dynamic buffer
DynaBuf_add_string(GlobalDynaBuf, env_var);
DynaBuf_append(GlobalDynaBuf, '\\'); // add dir separator
DynaBuf_append(GlobalDynaBuf, '\0'); // add terminator
DOS_lib_prefix = DynaBuf_get_copy(GlobalDynaBuf);
dynabuf_add_string(GlobalDynaBuf, env_var);
dynabuf_append(GlobalDynaBuf, '\\'); // add dir separator
dynabuf_append(GlobalDynaBuf, '\0'); // add terminator
DOS_lib_prefix = dynabuf_get_copy(GlobalDynaBuf);
}
}

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
//
// Platform specific stuff (in this case, for unknown OSes)
@ -24,12 +24,12 @@ void AnyOS_entry(void)
env_var = getenv("ACME");
// if environment variable was found, make a copy
if (env_var) {
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
// copy environment variable to global dynamic buffer
DynaBuf_add_string(GlobalDynaBuf, env_var);
DynaBuf_append(GlobalDynaBuf, '/'); // add dir separator
DynaBuf_append(GlobalDynaBuf, '\0'); // add terminator
AnyOS_lib_prefix = DynaBuf_get_copy(GlobalDynaBuf);
dynabuf_add_string(GlobalDynaBuf, env_var);
dynabuf_append(GlobalDynaBuf, '/'); // add dir separator
dynabuf_append(GlobalDynaBuf, '\0'); // add terminator
AnyOS_lib_prefix = dynabuf_get_copy(GlobalDynaBuf);
}
}

View File

@ -331,10 +331,10 @@ static boolean do_actual_work(void)
// copy string to DynaBuf
static void keyword_to_dynabuf(const char keyword[])
{
DYNABUF_CLEAR(GlobalDynaBuf);
DynaBuf_add_string(GlobalDynaBuf, keyword);
DynaBuf_append(GlobalDynaBuf, '\0');
DynaBuf_to_lower(GlobalDynaBuf, GlobalDynaBuf); // convert to lower case
dynabuf_clear(GlobalDynaBuf);
dynabuf_add_string(GlobalDynaBuf, keyword);
dynabuf_append(GlobalDynaBuf, '\0');
dynabuf_to_lower(GlobalDynaBuf, GlobalDynaBuf); // convert to lower case
}
@ -447,14 +447,14 @@ static void define_symbol(const char definition[])
signed long value;
// copy definition to GlobalDynaBuf until '=' reached
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
while ((*walk != '=') && (*walk != '\0'))
DynaBuf_append(GlobalDynaBuf, *walk++);
dynabuf_append(GlobalDynaBuf, *walk++);
if ((*walk == '\0') || (walk[1] == '\0'))
could_not_parse(definition);
// TODO - if first char is double quote, maybe interpret as string instead of number?
value = string_to_number(walk + 1);
DynaBuf_append(GlobalDynaBuf, '\0');
dynabuf_append(GlobalDynaBuf, '\0');
symbol_define(value);
}

View File

@ -320,18 +320,18 @@ static void is_not_defined(struct symbol *optional_symbol, char *name, size_t le
optional_symbol->has_been_reported = TRUE;
}
DYNABUF_CLEAR(errormsg_dyna_buf);
DynaBuf_add_string(errormsg_dyna_buf, "Value not defined (");
dynabuf_clear(errormsg_dyna_buf);
dynabuf_add_string(errormsg_dyna_buf, "Value not defined (");
length += errormsg_dyna_buf->size;
DynaBuf_add_string(errormsg_dyna_buf, name);
dynabuf_add_string(errormsg_dyna_buf, name);
if (errormsg_dyna_buf->size < length) {
Bug_found("IllegalSymbolNameLength", errormsg_dyna_buf->size - length);
} else {
errormsg_dyna_buf->size = length;
}
DynaBuf_add_string(errormsg_dyna_buf, ").");
DynaBuf_append(errormsg_dyna_buf, '\0');
dynabuf_add_string(errormsg_dyna_buf, ").");
dynabuf_append(errormsg_dyna_buf, '\0');
Throw_error(errormsg_dyna_buf->buffer);
}
@ -412,7 +412,7 @@ static void parse_quoted(char closing_quote)
{
intval_t value;
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
if (Input_quoted_to_dynabuf(closing_quote))
goto fail; // unterminated or escaping error
@ -645,7 +645,7 @@ static void parse_function_call(void)
void *node_body;
// make lower case version of name in local dynamic buffer
DynaBuf_to_lower(function_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(function_dyna_buf, GlobalDynaBuf);
// search for tree item
if (Tree_easy_scan(function_tree, &node_body, function_dyna_buf)) {
PUSH_OP((struct op *) node_body);
@ -720,6 +720,9 @@ static int parse_octal_or_unpseudo(void) // now GotByte = '&'
if (Input_read_scope_and_symbol_name(&scope)) // now GotByte = illegal char
return 1; // error (no string given)
if ((GotByte == '?') && symbol_fix_dynamic_name())
return 1; // error
get_symbol_value(scope, GlobalDynaBuf->size - 1, unpseudo_count); // -1 to not count terminator
// } else if (...) {
// // anonymous symbol
@ -878,10 +881,10 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
switch (GotByte) {
case '+': // anonymous forward label
// count plus signs to build name of anonymous label
DYNABUF_CLEAR(GlobalDynaBuf);
do
dynabuf_clear(GlobalDynaBuf);
do {
DYNABUF_APPEND(GlobalDynaBuf, '+');
while (GetByte() == '+');
} while (GetByte() == '+');
ugly_length_kluge = GlobalDynaBuf->size; // FIXME - get rid of this!
symbol_fix_forward_anon_name(FALSE); // FALSE: do not increment counter
get_symbol_value(section_now->local_scope, ugly_length_kluge, 0); // no prefix, no unpseudo
@ -890,14 +893,14 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
case '-': // NEGATION operator or anonymous backward label
// count minus signs in case it's an anonymous backward label
perform_negation = FALSE;
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
do {
DYNABUF_APPEND(GlobalDynaBuf, '-');
perform_negation = !perform_negation;
} while (GetByte() == '-');
SKIPSPACE();
if (BYTE_FOLLOWS_ANON(GotByte)) {
DynaBuf_append(GlobalDynaBuf, '\0');
dynabuf_append(GlobalDynaBuf, '\0');
get_symbol_value(section_now->local_scope, GlobalDynaBuf->size - 1, 0); // no prefix, -1 to not count terminator, no unpseudo
goto now_expect_dyadic_op;
}
@ -982,8 +985,12 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
goto now_expect_dyadic_op;
}
// FIXME - here we have a problem, we need to put '.' into GlobalDynaBuf even though we have already skipped it!
// 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 ((GotByte == '?') && symbol_fix_dynamic_name()) {
alu_state = STATE_ERROR;
break;//goto done;
}
get_symbol_value(scope, GlobalDynaBuf->size - 1, 0); // -1 to not count terminator, no unpseudo
goto now_expect_dyadic_op; // ok
}
@ -994,6 +1001,10 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
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 ((GotByte == '?') && symbol_fix_dynamic_name()) {
alu_state = STATE_ERROR;
break;//goto done;
}
get_symbol_value(scope, GlobalDynaBuf->size - 1, 0); // -1 to not count terminator, no unpseudo
goto now_expect_dyadic_op; // ok
}
@ -1034,6 +1045,8 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
// however, apart from that check above, function calls have nothing to do with
// parentheses: "sin(x+y)" gets parsed just like "not(x+y)".
} else {
if (GotByte == '?')
symbol_fix_dynamic_name();
get_symbol_value(SCOPE_GLOBAL, GlobalDynaBuf->size - 1, 0); // no prefix, -1 to not count terminator, no unpseudo
goto now_expect_dyadic_op;
}
@ -1234,17 +1247,17 @@ static void unsupported_operation(const struct object *optional, const struct op
if (op->group != OPGROUP_MONADIC)
Bug_found("OperatorIsNotMonadic", op->id);
}
DYNABUF_CLEAR(errormsg_dyna_buf);
DynaBuf_add_string(errormsg_dyna_buf, "Operation not supported: Cannot apply \"");
DynaBuf_add_string(errormsg_dyna_buf, op->text_version);
DynaBuf_add_string(errormsg_dyna_buf, "\" to \"");
dynabuf_clear(errormsg_dyna_buf);
dynabuf_add_string(errormsg_dyna_buf, "Operation not supported: Cannot apply \"");
dynabuf_add_string(errormsg_dyna_buf, op->text_version);
dynabuf_add_string(errormsg_dyna_buf, "\" to \"");
if (optional) {
DynaBuf_add_string(errormsg_dyna_buf, optional->type->name);
DynaBuf_add_string(errormsg_dyna_buf, "\" and \"");
dynabuf_add_string(errormsg_dyna_buf, optional->type->name);
dynabuf_add_string(errormsg_dyna_buf, "\" and \"");
}
DynaBuf_add_string(errormsg_dyna_buf, arg->type->name);
DynaBuf_add_string(errormsg_dyna_buf, "\".");
DynaBuf_append(errormsg_dyna_buf, '\0');
dynabuf_add_string(errormsg_dyna_buf, arg->type->name);
dynabuf_add_string(errormsg_dyna_buf, "\".");
dynabuf_append(errormsg_dyna_buf, '\0');
Throw_error(errormsg_dyna_buf->buffer);
}
@ -2309,20 +2322,20 @@ static void number_print(const struct object *self, struct dynabuf *db)
char buffer[NUMBUFSIZE];
if (self->u.number.ntype == NUMTYPE_UNDEFINED) {
DynaBuf_add_string(db, "<UNDEFINED NUMBER>");
dynabuf_add_string(db, "<UNDEFINED NUMBER>");
} else if (self->u.number.ntype == NUMTYPE_INT) {
#if _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L
snprintf(buffer, NUMBUFSIZE, "%ld (0x%lx)", (long) self->u.number.val.intval, (long) self->u.number.val.intval);
#else
sprintf(buffer, "%ld (0x%lx)", (long) self->u.number.val.intval, (long) self->u.number.val.intval);
#endif
DynaBuf_add_string(db, buffer);
dynabuf_add_string(db, buffer);
} else if (self->u.number.ntype == NUMTYPE_FLOAT) {
// write up to 30 significant characters.
// remaining 10 should suffice for sign,
// decimal point, exponent, terminator etc.
sprintf(buffer, "%.30g", self->u.number.val.fpval);
DynaBuf_add_string(db, buffer);
dynabuf_add_string(db, buffer);
} else {
Bug_found("IllegalNumberType5", self->u.number.ntype);
}
@ -2337,24 +2350,24 @@ static void list_print(const struct object *self, struct dynabuf *db)
struct object *obj;
const char *prefix = ""; // first item does not get a prefix
DynaBuf_append(db, '[');
dynabuf_append(db, '[');
length = self->u.listhead->u.listinfo.length;
item = self->u.listhead->next;
while (length--) {
obj = &item->u.payload;
DynaBuf_add_string(db, prefix);
dynabuf_add_string(db, prefix);
obj->type->print(obj, db);
item = item->next;
prefix = ", "; // following items are prefixed
}
DynaBuf_append(db, ']');
dynabuf_append(db, ']');
}
// string:
// print value for user message
static void string_print(const struct object *self, struct dynabuf *db)
{
DynaBuf_add_string(db, self->u.string->payload); // there is a terminator after the actual payload, so this works
dynabuf_add_string(db, self->u.string->payload); // there is a terminator after the actual payload, so this works
}
// number:

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
//
// Dynamic buffer stuff
@ -79,7 +79,7 @@ void dynabuf_enlarge(struct dynabuf *db)
// Claim enough memory to hold a copy of the current buffer contents,
// make that copy and return it.
// The copy must be released by calling free().
char *DynaBuf_get_copy(struct dynabuf *db)
char *dynabuf_get_copy(struct dynabuf *db)
{
char *copy;
@ -89,13 +89,13 @@ char *DynaBuf_get_copy(struct dynabuf *db)
}
// add char to buffer
void DynaBuf_append(struct dynabuf *db, char byte)
void dynabuf_append(struct dynabuf *db, char byte)
{
DYNABUF_APPEND(db, byte);
}
// Append string to buffer (without terminator)
void DynaBuf_add_string(struct dynabuf *db, const char *string)
void dynabuf_add_string(struct dynabuf *db, const char *string)
{
char byte;
@ -113,7 +113,7 @@ static char *ensure_free_space(struct dynabuf *db, int size)
}*/
// Convert buffer contents to lower case (target and source may be identical)
void DynaBuf_to_lower(struct dynabuf *target, struct dynabuf *source)
void dynabuf_to_lower(struct dynabuf *target, struct dynabuf *source)
{
char *read,
*write,

View File

@ -45,18 +45,22 @@ extern struct dynabuf GlobalDynaBuf[1]; // global dynamic buffer
// (ensure buffer is ready to use, then) clear dynamic buffer
#define DYNABUF_CLEAR(db) dynabuf_clear(db) // TODO - remove old macro
extern void dynabuf_clear(struct dynabuf *db);
// call whenever buffer is too small
extern void dynabuf_enlarge(struct dynabuf *db);
// return malloc'd copy of buffer contents
extern char *DynaBuf_get_copy(struct dynabuf *db);
extern char *dynabuf_get_copy(struct dynabuf *db);
// copy string to buffer (without terminator)
extern void DynaBuf_add_string(struct dynabuf *db, const char *);
extern void dynabuf_add_string(struct dynabuf *db, const char *);
// converts buffer contents to lower case
extern void DynaBuf_to_lower(struct dynabuf *target, struct dynabuf *source);
extern void dynabuf_to_lower(struct dynabuf *target, struct dynabuf *source);
// add char to buffer
extern void DynaBuf_append(struct dynabuf *db, char);
extern void dynabuf_append(struct dynabuf *db, char);
#endif

View File

@ -155,7 +155,7 @@ static void copy_condition(struct condition *condition, char terminator)
int err;
SKIPSPACE();
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
while ((GotByte != terminator) && (GotByte != CHAR_EOS)) {
// append to GlobalDynaBuf and check for quotes
DYNABUF_APPEND(GlobalDynaBuf, GotByte);
@ -168,8 +168,8 @@ static void copy_condition(struct condition *condition, char terminator)
}
GetByte();
}
DynaBuf_append(GlobalDynaBuf, CHAR_EOS); // ensure terminator
condition->body = DynaBuf_get_copy(GlobalDynaBuf);
dynabuf_append(GlobalDynaBuf, CHAR_EOS); // ensure terminator
condition->body = dynabuf_get_copy(GlobalDynaBuf);
}
// try to read a condition into DynaBuf and store pointer to copy in

View File

@ -208,6 +208,9 @@ static void parse_symbol_definition(scope_t scope, bits stat_flags)
{
bits force_bit;
if (GotByte == '?')
symbol_fix_dynamic_name();
force_bit = Input_get_force_bit(); // skips spaces after (yes, force bit is allowed for label definitions)
if (GotByte == '=') {
// explicit symbol definition (symbol = <something>)
@ -259,11 +262,11 @@ static void parse_backward_anon_def(bits *statement_flags)
if (!first_label_of_statement(statement_flags))
return;
DYNABUF_CLEAR(GlobalDynaBuf);
do
dynabuf_clear(GlobalDynaBuf);
do {
DYNABUF_APPEND(GlobalDynaBuf, '-');
while (GetByte() == '-');
DynaBuf_append(GlobalDynaBuf, '\0');
} while (GetByte() == '-');
dynabuf_append(GlobalDynaBuf, '\0');
// backward anons change their value!
set_label(section_now->local_scope, *statement_flags, NO_FORCE_BIT, POWER_CHANGE_VALUE);
}
@ -275,14 +278,14 @@ static void parse_forward_anon_def(bits *statement_flags)
if (!first_label_of_statement(statement_flags))
return;
DYNABUF_CLEAR(GlobalDynaBuf);
DynaBuf_append(GlobalDynaBuf, '+');
dynabuf_clear(GlobalDynaBuf);
dynabuf_append(GlobalDynaBuf, '+');
while (GotByte == '+') {
DYNABUF_APPEND(GlobalDynaBuf, '+');
GetByte();
}
symbol_fix_forward_anon_name(TRUE); // TRUE: increment counter
DynaBuf_append(GlobalDynaBuf, '\0');
dynabuf_append(GlobalDynaBuf, '\0');
//printf("[%d, %s]\n", section_now->local_scope, GlobalDynaBuf->buffer);
set_label(section_now->local_scope, *statement_flags, NO_FORCE_BIT, POWER_NONE);
}

View File

@ -369,7 +369,7 @@ int Input_quoted_to_dynabuf(char closing_quote)
{
boolean escaped = FALSE;
//DYNABUF_CLEAR(GlobalDynaBuf); // do not clear, caller might want to append to existing contents (TODO - check!)
//dynabuf_clear(GlobalDynaBuf); // do not clear, caller might want to append to existing contents (TODO - check!)
for (;;) {
GetQuotedByte();
if (GotByte == CHAR_EOS)
@ -463,7 +463,7 @@ char *Input_skip_or_store_block(boolean store)
int depth = 1; // to find matching block end
// prepare global dynamic buffer
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
do {
byte = GetByte();
// store
@ -492,10 +492,10 @@ char *Input_skip_or_store_block(boolean store)
// otherwise, prepare to return copy of block
// add EOF, just to make sure block is never read too far
DynaBuf_append(GlobalDynaBuf, CHAR_EOS);
DynaBuf_append(GlobalDynaBuf, CHAR_EOF);
dynabuf_append(GlobalDynaBuf, CHAR_EOS);
dynabuf_append(GlobalDynaBuf, CHAR_EOF);
// return pointer to copy
return DynaBuf_get_copy(GlobalDynaBuf);
return dynabuf_get_copy(GlobalDynaBuf);
}
// Append to GlobalDynaBuf while characters are legal for keywords.
@ -524,7 +524,7 @@ int Input_append_symbol_name_to_global_dynabuf(void)
{
if ((GotByte == LOCAL_PREFIX)
|| (GotByte == CHEAP_PREFIX)) {
DynaBuf_append(GlobalDynaBuf, GotByte);
dynabuf_append(GlobalDynaBuf, GotByte);
GetByte();
} else if (!BYTE_STARTS_KEYWORD(GotByte)) {
// FIXME - show invalid char in error message!
@ -541,19 +541,19 @@ int Input_readscopeandsymbolname(scope_t *scope, boolean dotkluge)
int err;
SKIPSPACE();
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
if (dotkluge) {
// this happens after the expression parser has eaten the '.'
// and did not find a decimal digit. -> not a float value ->
// must be a local symbol -> we must restore the '.' in front!
DynaBuf_append(GlobalDynaBuf, '.');
dynabuf_append(GlobalDynaBuf, '.');
err = append_keyword_to_global_dynabuf() == 0; // zero length -> error!
} else {
err = Input_append_symbol_name_to_global_dynabuf();
}
// add terminator to buffer (increments buffer's length counter)
DynaBuf_append(GlobalDynaBuf, '\0');
dynabuf_append(GlobalDynaBuf, '\0');
if (err) {
*scope = SCOPE_GLOBAL; // bogus, but at least not un-initialized
return 1; // error
@ -576,10 +576,10 @@ int Input_read_keyword(void)
{
int length;
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
length = append_keyword_to_global_dynabuf();
// add terminator to buffer (increments buffer's length counter)
DynaBuf_append(GlobalDynaBuf, '\0');
dynabuf_append(GlobalDynaBuf, '\0');
return length;
}
@ -591,11 +591,11 @@ int Input_read_and_lower_keyword(void)
{
int length;
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
length = append_keyword_to_global_dynabuf();
// add terminator to buffer (increments buffer's length counter)
DynaBuf_append(GlobalDynaBuf, '\0');
DynaBuf_to_lower(GlobalDynaBuf, GlobalDynaBuf); // convert to lower case
dynabuf_append(GlobalDynaBuf, '\0');
dynabuf_to_lower(GlobalDynaBuf, GlobalDynaBuf); // convert to lower case
return length;
}
@ -614,7 +614,7 @@ int Input_read_filename(boolean allow_library, boolean *uses_lib)
char *lib_prefix,
terminator;
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
SKIPSPACE();
switch (GotByte) {
case '<': // library access
@ -636,7 +636,7 @@ int Input_read_filename(boolean allow_library, boolean *uses_lib)
}
#endif
// copy lib path and set quoting char
DynaBuf_add_string(GlobalDynaBuf, lib_prefix);
dynabuf_add_string(GlobalDynaBuf, lib_prefix);
terminator = '>';
break;
case '"': // normal access
@ -666,7 +666,7 @@ int Input_read_filename(boolean allow_library, boolean *uses_lib)
return 1; // escaping error
// terminate string
DynaBuf_append(GlobalDynaBuf, '\0');
dynabuf_append(GlobalDynaBuf, '\0');
#ifdef PLATFORM_CONVERTPATH
// platform-specific path name conversion
PLATFORM_CONVERTPATH(GLOBALDYNABUF_CURRENT + start_of_string);
@ -747,18 +747,18 @@ FILE *includepaths_open_ro(boolean uses_lib)
// if failed and not lib, try include paths:
if ((stream == NULL) && !uses_lib) {
for (ipi = ipi_head.next; ipi != &ipi_head; ipi = ipi->next) {
DYNABUF_CLEAR(pathbuf);
dynabuf_clear(pathbuf);
// add first part
DynaBuf_add_string(pathbuf, ipi->path);
dynabuf_add_string(pathbuf, ipi->path);
// if wanted and possible, ensure last char is directory separator
if (DIRECTORY_SEPARATOR
&& pathbuf->size
&& (pathbuf->buffer[pathbuf->size - 1] != DIRECTORY_SEPARATOR))
DynaBuf_append(pathbuf, DIRECTORY_SEPARATOR);
dynabuf_append(pathbuf, DIRECTORY_SEPARATOR);
// add second part
DynaBuf_add_string(pathbuf, GLOBALDYNABUF_CURRENT);
dynabuf_add_string(pathbuf, GLOBALDYNABUF_CURRENT);
// terminate
DynaBuf_append(pathbuf, '\0');
dynabuf_append(pathbuf, '\0');
// try
stream = fopen(pathbuf->buffer, FILE_READBINARY);
//printf("trying <<%s>> - ", pathbuf->buffer);
@ -772,11 +772,11 @@ FILE *includepaths_open_ro(boolean uses_lib)
}
if (stream == NULL) {
// CAUTION, I'm re-using the path dynabuf to assemble the error message:
DYNABUF_CLEAR(pathbuf);
DynaBuf_add_string(pathbuf, "Cannot open input file \"");
DynaBuf_add_string(pathbuf, GLOBALDYNABUF_CURRENT);
DynaBuf_add_string(pathbuf, "\".");
DynaBuf_append(pathbuf, '\0');
dynabuf_clear(pathbuf);
dynabuf_add_string(pathbuf, "Cannot open input file \"");
dynabuf_add_string(pathbuf, GLOBALDYNABUF_CURRENT);
dynabuf_add_string(pathbuf, "\".");
dynabuf_append(pathbuf, '\0');
Throw_error(pathbuf->buffer);
}
//fprintf(stderr, "File is [%s]\n", GLOBALDYNABUF_CURRENT);

View File

@ -77,12 +77,12 @@ static scope_t get_scope_and_title(void)
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);
DynaBuf_add_string(user_macro_name, GLOBALDYNABUF_CURRENT);
DynaBuf_append(user_macro_name, '\0');
DYNABUF_CLEAR(internal_name);
DynaBuf_add_string(internal_name, GLOBALDYNABUF_CURRENT);
DynaBuf_append(internal_name, ARG_SEPARATOR);
dynabuf_clear(user_macro_name);
dynabuf_add_string(user_macro_name, GLOBALDYNABUF_CURRENT);
dynabuf_append(user_macro_name, '\0');
dynabuf_clear(internal_name);
dynabuf_add_string(internal_name, GLOBALDYNABUF_CURRENT);
dynabuf_append(internal_name, ARG_SEPARATOR);
SKIPSPACE(); // done here once so it's not necessary at two callers
return macro_scope;
}
@ -116,11 +116,11 @@ static char *get_string_copy(const char *original)
// Then try to find macro and return whether it was created.
static int search_for_macro(struct rwnode **result, scope_t scope, int create)
{
DynaBuf_append(internal_name, '\0'); // terminate macro name
dynabuf_append(internal_name, '\0'); // terminate macro name
// now internal_name = macro_title SPC argument_specifiers NUL
DYNABUF_CLEAR(GlobalDynaBuf);
DynaBuf_add_string(GlobalDynaBuf, internal_name->buffer);
DynaBuf_append(GlobalDynaBuf, '\0');
dynabuf_clear(GlobalDynaBuf);
dynabuf_add_string(GlobalDynaBuf, internal_name->buffer);
dynabuf_append(GlobalDynaBuf, '\0');
return Tree_hard_scan(result, macro_forest, scope, create);
}
@ -155,7 +155,7 @@ void Macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
scope_t macro_scope = get_scope_and_title();
// now GotByte = first non-space after title
DYNABUF_CLEAR(GlobalDynaBuf); // prepare to hold formal parameters
dynabuf_clear(GlobalDynaBuf); // prepare to hold formal parameters
// GlobalDynaBuf = "" (will hold formal parameter list)
// user_macro_name = MacroTitle NUL
// internal_name = MacroTitle ARG_SEPARATOR (grows to signature)
@ -172,10 +172,10 @@ void Macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
do {
// handle call-by-reference character ('~')
if (GotByte != REFERENCE_CHAR) {
DynaBuf_append(internal_name, ARGTYPE_VALUE);
dynabuf_append(internal_name, ARGTYPE_VALUE);
} else {
DynaBuf_append(internal_name, ARGTYPE_REF);
DynaBuf_append(GlobalDynaBuf, REFERENCE_CHAR);
dynabuf_append(internal_name, ARGTYPE_REF);
dynabuf_append(GlobalDynaBuf, REFERENCE_CHAR);
GetByte();
}
// handle symbol name (including '.'/'@' prefix)
@ -185,10 +185,10 @@ void Macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace);
}
DynaBuf_append(GlobalDynaBuf, CHAR_EOS); // terminate param list
dynabuf_append(GlobalDynaBuf, CHAR_EOS); // terminate param list
// now GlobalDynaBuf = comma-separated parameter list without spaces,
// but terminated with CHAR_EOS.
formal_parameters = DynaBuf_get_copy(GlobalDynaBuf);
formal_parameters = dynabuf_get_copy(GlobalDynaBuf);
// now GlobalDynaBuf = unused
// Reading the macro body would change the line number. To have correct
// error messages, we're checking for "macro twice" *now*.
@ -249,14 +249,14 @@ void Macro_parse_call(void) // Now GotByte = first char of macro name
// In both cases, GlobalDynaBuf may be used.
if (GotByte == REFERENCE_CHAR) {
// read call-by-reference arg
DynaBuf_append(internal_name, ARGTYPE_REF);
dynabuf_append(internal_name, ARGTYPE_REF);
GetByte(); // eat '~'
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 {
// read call-by-value arg
DynaBuf_append(internal_name, ARGTYPE_VALUE);
dynabuf_append(internal_name, ARGTYPE_VALUE);
ALU_any_result(&(arg_table[arg_count].result));
}
++arg_count;

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
//
// Mnemonics stuff
@ -1215,7 +1215,7 @@ boolean keyword_is_6502_mnemo(int length)
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
return check_mnemo_tree(mnemo_6502_tree, mnemo_dyna_buf);
}
@ -1226,7 +1226,7 @@ boolean keyword_is_nmos6502_mnemo(int length)
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
// first check undocumented ("illegal") opcodes...
if (check_mnemo_tree(mnemo_6502undoc1_tree, mnemo_dyna_buf))
return TRUE;
@ -1246,7 +1246,7 @@ boolean keyword_is_c64dtv2_mnemo(int length)
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
// first check C64DTV2 extensions...
if (check_mnemo_tree(mnemo_c64dtv2_tree, mnemo_dyna_buf))
return TRUE;
@ -1266,7 +1266,7 @@ boolean keyword_is_65c02_mnemo(int length)
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
// first check extensions because some mnemonics gained new addressing modes...
if (check_mnemo_tree(mnemo_65c02_tree, mnemo_dyna_buf))
return TRUE;
@ -1282,7 +1282,7 @@ boolean keyword_is_r65c02_mnemo(int length)
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
// first check 65c02 extensions because some mnemonics gained new addressing modes...
if (check_mnemo_tree(mnemo_65c02_tree, mnemo_dyna_buf))
return TRUE;
@ -1302,7 +1302,7 @@ boolean keyword_is_w65c02_mnemo(int length)
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
// first check 65c02 extensions because some mnemonics gained new addressing modes...
if (check_mnemo_tree(mnemo_65c02_tree, mnemo_dyna_buf))
return TRUE;
@ -1326,7 +1326,7 @@ boolean keyword_is_65ce02_mnemo(int length)
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
// first check 65ce02 extensions because some mnemonics gained new addressing modes...
if (check_mnemo_tree(mnemo_65ce02_tree, mnemo_dyna_buf))
return TRUE;
@ -1354,7 +1354,7 @@ boolean keyword_is_4502_mnemo(int length)
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
// first check 65ce02 extensions because some mnemonics gained new addressing modes...
if (check_mnemo_tree(mnemo_65ce02_tree, mnemo_dyna_buf))
return TRUE;
@ -1382,7 +1382,7 @@ boolean keyword_is_m65_mnemo(int length)
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
// first check m65 extensions because some mnemonics gained new addressing modes...
if (check_mnemo_tree(mnemo_m65_tree, mnemo_dyna_buf))
return TRUE;
@ -1414,7 +1414,7 @@ boolean keyword_is_65816_mnemo(int length)
return FALSE;
// make lower case version of mnemonic in local dynamic buffer
DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
dynabuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf);
// first check 65816 extensions because some mnemonics gained new addressing modes...
if (check_mnemo_tree(mnemo_65816_tree, mnemo_dyna_buf))
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
//
// Output stuff
@ -270,7 +270,7 @@ int outputfile_set_filename(void)
}
// get malloc'd copy of filename
output_filename = DynaBuf_get_copy(GlobalDynaBuf);
output_filename = dynabuf_get_copy(GlobalDynaBuf);
return 0; // ok
}

View File

@ -392,7 +392,7 @@ static enum eos encode_string(const struct encoder *inner_encoder, unsigned char
// the old way of handling string literals:
int offset;
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
if (Input_quoted_to_dynabuf('"'))
return SKIP_REMAINDER; // unterminated or escaping error
@ -787,7 +787,7 @@ static enum eos po_symbollist(void)
}
// get malloc'd copy of filename
symbollist_filename = DynaBuf_get_copy(GlobalDynaBuf);
symbollist_filename = dynabuf_get_copy(GlobalDynaBuf);
// ensure there's no garbage at end of line
return ENSURE_EOS;
}
@ -811,7 +811,7 @@ static enum eos po_zone(void)
// because we know of one character for sure,
// there's no need to check the return value.
Input_read_keyword();
new_title = DynaBuf_get_copy(GlobalDynaBuf);
new_title = dynabuf_get_copy(GlobalDynaBuf);
allocated = TRUE;
}
// setup new section
@ -1258,11 +1258,11 @@ static enum eos throw_string(const char prefix[], void (*fn)(const char *))
{
struct object object;
DYNABUF_CLEAR(user_message);
DynaBuf_add_string(user_message, prefix);
dynabuf_clear(user_message);
dynabuf_add_string(user_message, prefix);
do {
if ((GotByte == '"') && (config.wanted_version < VER_BACKSLASHESCAPING)) {
DYNABUF_CLEAR(GlobalDynaBuf);
dynabuf_clear(GlobalDynaBuf);
if (Input_quoted_to_dynabuf('"'))
return SKIP_REMAINDER; // unterminated or escaping error
@ -1272,15 +1272,15 @@ static enum eos throw_string(const char prefix[], void (*fn)(const char *))
if (Input_unescape_dynabuf(0))
return SKIP_REMAINDER; // escaping error
DynaBuf_append(GlobalDynaBuf, '\0'); // terminate string
DynaBuf_add_string(user_message, GLOBALDYNABUF_CURRENT); // add to message
dynabuf_append(GlobalDynaBuf, '\0'); // terminate string
dynabuf_add_string(user_message, GLOBALDYNABUF_CURRENT); // add to message
} else {
// parse value
ALU_any_result(&object);
object.type->print(&object, user_message);
}
} while (Input_accept_comma());
DynaBuf_append(user_message, '\0');
dynabuf_append(user_message, '\0');
fn(user_message->buffer);
return ENSURE_EOS;
}

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
//
// symbol stuff
@ -252,7 +252,7 @@ void symbol_fix_forward_anon_name(boolean increment)
unsigned long number;
// terminate name, find "counter" symbol and read value
DynaBuf_append(GlobalDynaBuf, '\0');
dynabuf_append(GlobalDynaBuf, '\0');
counter_symbol = symbol_find(section_now->local_scope);
if (counter_symbol->object.type == NULL) {
// finish freshly created symbol item
@ -277,7 +277,57 @@ void symbol_fix_forward_anon_name(boolean increment)
DYNABUF_APPEND(GlobalDynaBuf, 'a' + (number & 15));
number >>= 4;
} while (number);
DynaBuf_append(GlobalDynaBuf, '\0');
dynabuf_append(GlobalDynaBuf, '\0');
if (increment)
counter_symbol->object.u.number.val.intval++;
}
// temporary buffer for base name while handling second part
STRUCT_DYNABUF_REF(basename_db, 64);
// replace dynamic symbol name with its final version.
// ("basename?indexsymbol" -> "basename4711")
// on entry: GlobalDynaBuf holds base name, GotByte holds '?'
// on exit: GlobalDynaBuf holds fixed name
// return whether there was an error.
#define NUMBUFSIZE 64 // large enough(tm) even for 64bit systems
int symbol_fix_dynamic_name(void)
{
scope_t second_scope;
struct symbol *second_symbol;
char numbuf[NUMBUFSIZE];
if (GotByte != '?')
Bug_found("NotQuestionMark", GotByte);
GetByte(); // eat '?' character
// remember base name
dynabuf_clear(basename_db);
dynabuf_add_string(basename_db, GLOBALDYNABUF_CURRENT);
dynabuf_append(basename_db, '\0'); // terminate
// read second part (CAUTION, this will overwrite GlobalDynaBuf!)
if (Input_read_scope_and_symbol_name(&second_scope))
return 1;
second_symbol = symbol_find(second_scope);
if (second_symbol->object.type != &type_number) {
Throw_error("Second part of dynamic symbol name is not a number.");
return 1;
}
if (second_symbol->object.u.number.ntype != NUMTYPE_INT) {
Throw_error("Second part of dynamic symbol name is undefined or not integer.");
return 1;
}
second_symbol->has_been_read = TRUE;
#if _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L
snprintf(numbuf, NUMBUFSIZE, "%ld", (long) second_symbol->object.u.number.val.intval);
#else
sprintf(numbuf, "%ld", (long) second_symbol->object.u.number.val.intval);
#endif
// return basename and number in GlobalDynaBuf:
dynabuf_clear(GlobalDynaBuf);
dynabuf_add_string(GlobalDynaBuf, basename_db->buffer);
dynabuf_add_string(GlobalDynaBuf, numbuf);
dynabuf_append(GlobalDynaBuf, '\0');
//printf("skipping '?' for <%s>\n", GLOBALDYNABUF_CURRENT);
return 0;
}

View File

@ -58,5 +58,9 @@ extern void symbols_vicelabels(FILE *fd);
// so it references the *next* anonymous forward label definition.
extern void symbol_fix_forward_anon_name(boolean increment);
// replace name of dynamic symbol with its final version.
// return whether there was an error.
extern int symbol_fix_dynamic_name(void);
#endif

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2021 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// tree stuff
@ -179,7 +179,7 @@ int Tree_hard_scan(struct rwnode **result, struct rwnode **forest, int id_number
new_leaf_node->less_than_or_equal = NULL;
new_leaf_node->hash_value = wanted.hash_value;
new_leaf_node->id_number = id_number;
new_leaf_node->id_string = DynaBuf_get_copy(GlobalDynaBuf); // make permanent copy
new_leaf_node->id_string = dynabuf_get_copy(GlobalDynaBuf); // make permanent copy
// add new leaf to tree
*current_node = new_leaf_node;
// store pointer to new node in result location

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME
#define CODENAME "Zem" // update before release
#define CHANGE_DATE "28 Jan" // update before release FIXME
#define CHANGE_DATE "29 Jan" // 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