From 45bb65d74d165739b34f71dbfeb1817c7b539dd0 Mon Sep 17 00:00:00 2001 From: marcobaye Date: Sun, 3 Mar 2024 14:31:08 +0000 Subject: [PATCH] Un-pseudopc-operator '&' can now be applied to all address symbols, not only to implicitly defined labels. git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@354 4df02467-bbd4-4a76-a152-e7ce94205b78 --- docs/Errors.txt | 19 ++++++------- src/global.c | 2 -- src/output.c | 2 +- src/symbol.c | 41 ++++++++++++++++------------- src/version.h | 2 +- testing/auto/unpseudo.a | 18 +++++++++++-- testing/errors/nopseudopccontext1.a | 4 +-- testing/errors/nopseudopccontext2.a | 2 +- testing/errors/nopseudopccontext3.a | 9 +++++++ testing/errors/nopseudopccontext4.a | 2 ++ 10 files changed, 64 insertions(+), 37 deletions(-) create mode 100644 testing/errors/nopseudopccontext3.a create mode 100644 testing/errors/nopseudopccontext4.a diff --git a/docs/Errors.txt b/docs/Errors.txt index 4fc4d8d..2083000 100644 --- a/docs/Errors.txt +++ b/docs/Errors.txt @@ -392,19 +392,20 @@ Un-pseudopc operator '&' can only be applied to number symbols. operator only works on labels and on '*' (the program counter), it cannot be used on other objects. -Un-pseudopc operator '&' only works on labels. - You tried to apply the operator '&' to something that is not an - implicitly defined label, but the result of an explicit symbol - assignment (like the result of a calculation). Example: +Un-pseudopc operator '&' only works on addresses. + You tried to apply the operator '&' to something that is neither + the program counter nor an implicitly defined label nor something + derived from those. Example: argument = * + 1 label lda #$ff - You can use '&' on "label", but not on "argument". + dummy = 500 + You can use '&' on "label" and on "argument", but not on "dummy". Un-pseudopc operator '&' has no !pseudopc context. - You tried to apply the operator '&' to a label that was defined - outside of a !pseudopc block, or, more generally, the number of - '&' characters used was larger than the number of !pseudopc blocks - around the definition. + You tried to apply the operator '&' to an address symbol that was + defined outside of a !pseudopc block, or, more generally, the + number of '&' characters used was larger than the number of + !pseudopc blocks around the definition. Unknown encoding. You used the "!convtab" pseudo opcode with a keyword ACME does not diff --git a/src/global.c b/src/global.c index 7aede8f..e02a544 100644 --- a/src/global.c +++ b/src/global.c @@ -224,8 +224,6 @@ static void set_label(scope_t scope, bits force_bit, bits powers) symbol_set_object(symbol, &result, powers); if (force_bit) symbol_set_force_bit(symbol, force_bit); -// FIXME - move this to symbol_set_object() and call it for all address symbols! - symbol->pseudopc = pseudopc_get_context(); // global labels must open new scope for cheap locals if (scope == SCOPE_GLOBAL) section_new_cheap_scope(section_now); diff --git a/src/output.c b/src/output.c index 422a6fe..c91dd23 100644 --- a/src/output.c +++ b/src/output.c @@ -574,7 +574,7 @@ int pseudopc_unpseudo(struct number *target, struct pseudopc *context, unsigned return 0; // ok (no sense in trying to unpseudo this, and it might be an unresolved forward ref anyway) if (context == NULL) { - Throw_error("Un-pseudopc operator '&' only works on labels."); + Throw_error("Un-pseudopc operator '&' only works on addresses."); return 1; // error } if (context == &outermost_pseudopc_context) { diff --git a/src/symbol.c b/src/symbol.c index 060374a..0c965bc 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -142,31 +142,34 @@ struct symbol *symbol_find(scope_t scope) // CAUTION: actual incrementing of counter is then done directly without calls here! void symbol_set_object(struct symbol *symbol, struct object *new_value, bits powers) { - // if symbol has no object assigned to it yet, fine: if (symbol->object.type == NULL) { + // symbol has no object assigned to it yet symbol->object = *new_value; // copy whole struct including type // as long as the symbol has not been read, the force bits can // be changed, so the caller still has a chance to do that. - return; + } else { + // symbol already has an object + + // compare types + // if too different, needs power (or complains) + if (symbol->object.type != new_value->type) { + if (!(powers & POWER_CHANGE_OBJTYPE)) + Throw_error(exception_symbol_defined); + // CAUTION: if above line throws error, we still go ahead and change type! + // this is to keep "!for" working, where the counter var is accessed. + symbol->object = *new_value; // copy whole struct including type + // clear flag so caller can adjust force bits: + symbol->has_been_read = FALSE; // it's basically a new symbol now + } else { + // symbol and new value have compatible types, so call handler: + symbol->object.type->assign(&symbol->object, new_value, !!(powers & POWER_CHANGE_VALUE)); + } } - - // now we know symbol already has a type - - // compare types - // if too different, needs power (or complains) - if (symbol->object.type != new_value->type) { - if (!(powers & POWER_CHANGE_OBJTYPE)) - Throw_error(exception_symbol_defined); - // CAUTION: if above line throws error, we still go ahead and change type! - // this is to keep "!for" working, where the counter var is accessed. - symbol->object = *new_value; // copy whole struct including type - // clear flag so caller can adjust force bits: - symbol->has_been_read = FALSE; // it's basically a new symbol now - return; + // if symbol is an address, give it a pseudopc context: + if ((symbol->object.type == &type_number) + && (symbol->object.u.number.addr_refs == 1)) { + symbol->pseudopc = pseudopc_get_context(); } - - // now we know symbol and new value have compatible types, so call handler: - symbol->object.type->assign(&symbol->object, new_value, !!(powers & POWER_CHANGE_VALUE)); } diff --git a/src/version.h b/src/version.h index b7914a0..c34983e 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ #define RELEASE "0.97" // update before release FIXME #define CODENAME "Zem" // update before release -#define CHANGE_DATE "26 Feb" // update before release FIXME +#define CHANGE_DATE "27 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 diff --git a/testing/auto/unpseudo.a b/testing/auto/unpseudo.a index 7ee5d1f..e207f90 100644 --- a/testing/auto/unpseudo.a +++ b/testing/auto/unpseudo.a @@ -1,12 +1,26 @@ *=$1000 - nop +label1 nop !pseudopc $0300 { - nop +label2 nop !if * != $0301 { !error "pseudo pc is not $0301" } !if &* != $1002 { !error "un-pseudo'd pc is not $1002" } + selfmod = * + 1 + lda #$ff + + does_not_make_sense = label1 + 1 + *=$0380 nop !if * != $0381 { !error "pseudo pc is not $0381" } !if &* != $1082 { !error "un-pseudo'd pc is not $1082" } } !if * != $1082 { !error "pc is not $1082" } + + !if label2 != $0300 { !error "label2 is not $0300" } + !if &label2 != $1001 { !error "&label2 is not $1001" } + + !if selfmod != $0302 { !error "selfmod is not $0302" } + !if &selfmod != $1003 { !error "&selfmod is not $1003" } + + !if does_not_make_sense != $1001 { !error "dnms is not $1001" } + !if &does_not_make_sense != $1d02 { !error "dnms is not $1d02" } diff --git a/testing/errors/nopseudopccontext1.a b/testing/errors/nopseudopccontext1.a index e88213f..998ea58 100644 --- a/testing/errors/nopseudopccontext1.a +++ b/testing/errors/nopseudopccontext1.a @@ -1,3 +1,3 @@ *=$1000 -label nop - a = &label +label nop + a = &label ; -> "Un-pseudopc operator '&' has no !pseudopc context." diff --git a/testing/errors/nopseudopccontext2.a b/testing/errors/nopseudopccontext2.a index e05cf65..c7eb5fa 100644 --- a/testing/errors/nopseudopccontext2.a +++ b/testing/errors/nopseudopccontext2.a @@ -1,2 +1,2 @@ *=$1000 - b = &* + b = &* ; -> "Un-pseudopc operator '&' has no !pseudopc context." diff --git a/testing/errors/nopseudopccontext3.a b/testing/errors/nopseudopccontext3.a new file mode 100644 index 0000000..4db7d51 --- /dev/null +++ b/testing/errors/nopseudopccontext3.a @@ -0,0 +1,9 @@ + *=$1000 + !pseudopc $0300 { +label1 nop + label2 = label1 + 1 + dummy = $0500 + } + ;test = &label1 ; this works + ;test = &label2 ; this also works + err = &dummy ; -> "Un-pseudopc operator '&' only works on addresses." diff --git a/testing/errors/nopseudopccontext4.a b/testing/errors/nopseudopccontext4.a new file mode 100644 index 0000000..d2c258d --- /dev/null +++ b/testing/errors/nopseudopccontext4.a @@ -0,0 +1,2 @@ + primes = [2,3,5] + a = &primes ; -> "Un-pseudopc operator '&' can only be applied to number symbols."