mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-11-08 18:10:08 +00:00
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:
parent
8f9e3a5855
commit
45bb65d74d
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
41
src/symbol.c
41
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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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" }
|
||||
|
@ -1,3 +1,3 @@
|
||||
*=$1000
|
||||
label nop
|
||||
a = &label
|
||||
label nop
|
||||
a = &label ; -> "Un-pseudopc operator '&' has no !pseudopc context."
|
||||
|
@ -1,2 +1,2 @@
|
||||
*=$1000
|
||||
b = &*
|
||||
b = &* ; -> "Un-pseudopc operator '&' has no !pseudopc context."
|
||||
|
9
testing/errors/nopseudopccontext3.a
Normal file
9
testing/errors/nopseudopccontext3.a
Normal 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."
|
2
testing/errors/nopseudopccontext4.a
Normal file
2
testing/errors/nopseudopccontext4.a
Normal file
@ -0,0 +1,2 @@
|
||||
primes = [2,3,5]
|
||||
a = &primes ; -> "Un-pseudopc operator '&' can only be applied to number symbols."
|
Loading…
Reference in New Issue
Block a user