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
This commit is contained in:
marcobaye 2024-03-03 14:31:08 +00:00
parent 8f9e3a5855
commit 45bb65d74d
10 changed files with 64 additions and 37 deletions

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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));
}

View File

@ -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

View File

@ -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" }

View File

@ -1,3 +1,3 @@
*=$1000
label nop
a = &label
label nop
a = &label ; -> "Un-pseudopc operator '&' has no !pseudopc context."

View File

@ -1,2 +1,2 @@
*=$1000
b = &*
b = &* ; -> "Un-pseudopc operator '&' has no !pseudopc context."

View File

@ -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."

View File

@ -0,0 +1,2 @@
primes = [2,3,5]
a = &primes ; -> "Un-pseudopc operator '&' can only be applied to number symbols."