fixed bugs: trig functions did not clear FITS_BYTE flag, comparisons did not set it!

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@225 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2020-06-10 13:12:25 +00:00
parent 7c82984075
commit ec2b7515ca
9 changed files with 199 additions and 41 deletions

View File

@ -442,7 +442,7 @@ static void parse_quoted(char closing_quote)
Throw_error("There's more than one character."); Throw_error("There's more than one character.");
// parse character // parse character
value = (intval_t) (unsigned char) encoding_encode_char(GLOBALDYNABUF_CURRENT[0]); value = (intval_t) (unsigned char) encoding_encode_char(GLOBALDYNABUF_CURRENT[0]);
PUSH_INT_ARG(value, NUMBER_IS_DEFINED | NUMBER_FITS_BYTE, 0); PUSH_INT_ARG(value, NUMBER_IS_DEFINED | NUMBER_FITS_BYTE, 0); // FIXME - why set FITS_BYTE? it's only really useful for undefined values!
} }
// Now GotByte = char following closing quote (or CHAR_EOS on error) // Now GotByte = char following closing quote (or CHAR_EOS on error)
return; return;
@ -1126,7 +1126,7 @@ static void unsupported_operation(struct object *optional, struct op *op, struct
static void int_create_byte(struct object *self, intval_t byte) static void int_create_byte(struct object *self, intval_t byte)
{ {
self->type = &type_int; self->type = &type_int;
self->u.number.flags = NUMBER_IS_DEFINED | NUMBER_FITS_BYTE; self->u.number.flags = NUMBER_IS_DEFINED | NUMBER_FITS_BYTE; // FIXME - if DEFINED anyway, what use is there for FITS_BYTE?
self->u.number.val.intval = byte; self->u.number.val.intval = byte;
self->u.number.addr_refs = 0; self->u.number.addr_refs = 0;
} }
@ -1259,21 +1259,27 @@ static void float_handle_monadic_operator(struct object *self, struct op *op)
break; break;
case OPID_SIN: case OPID_SIN:
self->u.number.val.fpval = sin(self->u.number.val.fpval); self->u.number.val.fpval = sin(self->u.number.val.fpval);
self->u.number.flags &= ~NUMBER_FITS_BYTE;
break; break;
case OPID_COS: case OPID_COS:
self->u.number.val.fpval = cos(self->u.number.val.fpval); self->u.number.val.fpval = cos(self->u.number.val.fpval);
self->u.number.flags &= ~NUMBER_FITS_BYTE;
break; break;
case OPID_TAN: case OPID_TAN:
self->u.number.val.fpval = tan(self->u.number.val.fpval); self->u.number.val.fpval = tan(self->u.number.val.fpval);
self->u.number.flags &= ~NUMBER_FITS_BYTE;
break; break;
case OPID_ARCSIN: case OPID_ARCSIN:
float_ranged_fn(asin, self); float_ranged_fn(asin, self);
self->u.number.flags &= ~NUMBER_FITS_BYTE;
break; break;
case OPID_ARCCOS: case OPID_ARCCOS:
float_ranged_fn(acos, self); float_ranged_fn(acos, self);
self->u.number.flags &= ~NUMBER_FITS_BYTE;
break; break;
case OPID_ARCTAN: case OPID_ARCTAN:
self->u.number.val.fpval = atan(self->u.number.val.fpval); self->u.number.val.fpval = atan(self->u.number.val.fpval);
self->u.number.flags &= ~NUMBER_FITS_BYTE;
break; break;
case OPID_NEGATE: case OPID_NEGATE:
self->u.number.val.fpval = -(self->u.number.val.fpval); self->u.number.val.fpval = -(self->u.number.val.fpval);
@ -1336,15 +1342,26 @@ static void string_handle_monadic_operator(struct object *self, struct op *op)
// int/float: // int/float:
// merge result flags // merge result flags
// (used by both int and float handlers for dyadic operators) // (used by both int and float handlers for comparison operators)
static void number_fix_result_after_comparison(struct object *self, struct object *other, intval_t result)
{
int flags;
self->type = &type_int;
self->u.number.val.intval = result;
self->u.number.addr_refs = 0;
flags = (self->u.number.flags & other->u.number.flags) & NUMBER_IS_DEFINED; // DEFINED flags are ANDed together
flags |= (self->u.number.flags | other->u.number.flags) & NUMBER_EVER_UNDEFINED; // EVER_UNDEFINED flags are ORd together
flags |= NUMBER_FITS_BYTE; // FITS_BYTE gets set
// (FORCEBITS are cleared)
self->u.number.flags = flags;
}
// (used by both int and float handlers for all other dyadic operators)
static void number_fix_result_after_dyadic(struct object *self, struct object *other) static void number_fix_result_after_dyadic(struct object *self, struct object *other)
{ {
// EVER_UNDEFINED and FORCEBIT flags are ORd together self->u.number.flags |= other->u.number.flags & (NUMBER_EVER_UNDEFINED | NUMBER_FORCEBITS); // EVER_UNDEFINED and FORCEBITs are ORd together
self->u.number.flags |= other->u.number.flags & (NUMBER_EVER_UNDEFINED | NUMBER_FORCEBITS); self->u.number.flags &= (other->u.number.flags | ~NUMBER_IS_DEFINED); // DEFINED flags are ANDed together
// DEFINED flags are ANDed together self->u.number.flags &= ~NUMBER_FITS_BYTE; // FITS_BYTE is cleared
self->u.number.flags &= (other->u.number.flags | ~NUMBER_IS_DEFINED);
// FITS_BYTE is cleared
self->u.number.flags &= ~NUMBER_FITS_BYTE;
} }
@ -1460,24 +1477,17 @@ static void int_handle_dyadic_operator(struct object *self, struct op *op, struc
self->u.number.val.intval = ((uintval_t) (self->u.number.val.intval)) >> other->u.number.val.intval; self->u.number.val.intval = ((uintval_t) (self->u.number.val.intval)) >> other->u.number.val.intval;
break; break;
case OPID_LESSOREQUAL: case OPID_LESSOREQUAL:
// FIXME - all comparison results should clear all force bits and set fits_byte! also for floats! return number_fix_result_after_comparison(self, other, self->u.number.val.intval <= other->u.number.val.intval);
self->u.number.val.intval = (self->u.number.val.intval <= other->u.number.val.intval);
break;
case OPID_LESSTHAN: case OPID_LESSTHAN:
self->u.number.val.intval = (self->u.number.val.intval < other->u.number.val.intval); return number_fix_result_after_comparison(self, other, self->u.number.val.intval < other->u.number.val.intval);
break;
case OPID_GREATEROREQUAL: case OPID_GREATEROREQUAL:
self->u.number.val.intval = (self->u.number.val.intval >= other->u.number.val.intval); return number_fix_result_after_comparison(self, other, self->u.number.val.intval >= other->u.number.val.intval);
break;
case OPID_GREATERTHAN: case OPID_GREATERTHAN:
self->u.number.val.intval = (self->u.number.val.intval > other->u.number.val.intval); return number_fix_result_after_comparison(self, other, self->u.number.val.intval > other->u.number.val.intval);
break;
case OPID_NOTEQUAL: case OPID_NOTEQUAL:
self->u.number.val.intval = (self->u.number.val.intval != other->u.number.val.intval); return number_fix_result_after_comparison(self, other, self->u.number.val.intval != other->u.number.val.intval);
break;
case OPID_EQUALS: case OPID_EQUALS:
self->u.number.val.intval = (self->u.number.val.intval == other->u.number.val.intval); return number_fix_result_after_comparison(self, other, self->u.number.val.intval == other->u.number.val.intval);
break;
case OPID_AND: case OPID_AND:
self->u.number.val.intval &= other->u.number.val.intval; self->u.number.val.intval &= other->u.number.val.intval;
refs = self->u.number.addr_refs + other->u.number.addr_refs; // add address references refs = self->u.number.addr_refs + other->u.number.addr_refs; // add address references
@ -1500,6 +1510,7 @@ static void int_handle_dyadic_operator(struct object *self, struct op *op, struc
unsupported_operation(self, op, other); unsupported_operation(self, op, other);
return; return;
} }
// CAUTION: comparisons call number_fix_result_after_comparison instead of jumping here
self->u.number.addr_refs = refs; // update address refs with local copy self->u.number.addr_refs = refs; // update address refs with local copy
number_fix_result_after_dyadic(self, other); // fix result flags number_fix_result_after_dyadic(self, other); // fix result flags
} }
@ -1616,29 +1627,17 @@ static void float_handle_dyadic_operator(struct object *self, struct op *op, str
self->u.number.val.fpval /= (1 << other->u.number.val.intval); // FIXME - why not use pow() as in SL above? self->u.number.val.fpval /= (1 << other->u.number.val.intval); // FIXME - why not use pow() as in SL above?
break; break;
case OPID_LESSOREQUAL: case OPID_LESSOREQUAL:
self->u.number.val.intval = (self->u.number.val.fpval <= other->u.number.val.fpval); return number_fix_result_after_comparison(self, other, self->u.number.val.fpval <= other->u.number.val.fpval);
self->type = &type_int; // result is int
break;
case OPID_LESSTHAN: case OPID_LESSTHAN:
self->u.number.val.intval = (self->u.number.val.fpval < other->u.number.val.fpval); return number_fix_result_after_comparison(self, other, self->u.number.val.fpval < other->u.number.val.fpval);
self->type = &type_int; // result is int
break;
case OPID_GREATEROREQUAL: case OPID_GREATEROREQUAL:
self->u.number.val.intval = (self->u.number.val.fpval >= other->u.number.val.fpval); return number_fix_result_after_comparison(self, other, self->u.number.val.fpval >= other->u.number.val.fpval);
self->type = &type_int; // result is int
break;
case OPID_GREATERTHAN: case OPID_GREATERTHAN:
self->u.number.val.intval = (self->u.number.val.fpval > other->u.number.val.fpval); return number_fix_result_after_comparison(self, other, self->u.number.val.fpval > other->u.number.val.fpval);
self->type = &type_int; // result is int
break;
case OPID_NOTEQUAL: case OPID_NOTEQUAL:
self->u.number.val.intval = (self->u.number.val.fpval != other->u.number.val.fpval); return number_fix_result_after_comparison(self, other, self->u.number.val.fpval != other->u.number.val.fpval);
self->type = &type_int; // result is int
break;
case OPID_EQUALS: case OPID_EQUALS:
self->u.number.val.intval = (self->u.number.val.fpval == other->u.number.val.fpval); return number_fix_result_after_comparison(self, other, self->u.number.val.fpval == other->u.number.val.fpval);
self->type = &type_int; // result is int
break;
// add new dyadic operators here // add new dyadic operators here
// case OPID_: // case OPID_:
// break; // break;
@ -1646,6 +1645,7 @@ static void float_handle_dyadic_operator(struct object *self, struct op *op, str
unsupported_operation(self, op, other); unsupported_operation(self, op, other);
return; return;
} }
// CAUTION: comparisons call number_fix_result_after_comparison instead of jumping here
self->u.number.addr_refs = refs; // update address refs with local copy self->u.number.addr_refs = refs; // update address refs with local copy
number_fix_result_after_dyadic(self, other); // fix result flags number_fix_result_after_dyadic(self, other); // fix result flags
} }

View File

@ -9,7 +9,7 @@
#define RELEASE "0.96.5" // update before release FIXME #define RELEASE "0.96.5" // update before release FIXME
#define CODENAME "Fenchurch" // update before release #define CODENAME "Fenchurch" // update before release
#define CHANGE_DATE "9 June" // update before release FIXME #define CHANGE_DATE "10 June" // update before release FIXME
#define CHANGE_YEAR "2020" // update before release #define CHANGE_YEAR "2020" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME

View File

@ -1,2 +1,3 @@
;ACME 0.96.5
a = 3 a = 3
a = 3.0 ; -> "already defined" (type has changed) a = 3.0 ; -> "already defined" (type has changed)

View File

@ -1,2 +1,3 @@
;ACME 0.96.5
a = 3 a = 3
a = 4 ; -> "already defined" (value has changed) a = 4 ; -> "already defined" (value has changed)

View File

@ -1,3 +1,4 @@
;ACME 0.96.5
*=$1000 *=$1000
label label
nop nop

View File

@ -1,3 +1,4 @@
;ACME 0.96.5
a = 3 a = 3
b = a ; read a b = a ; read a
a+2 = 3 ; -> "too late for postfix" a+2 = 3 ; -> "too late for postfix"

View File

@ -1,3 +1,4 @@
;ACME 0.96.5
*=$1000 *=$1000
label label
b = label ; read symbol b = label ; read symbol

View File

@ -1,3 +1,4 @@
;ACME 0.96.5
; "assert" macro ; "assert" macro
!macro a @r { !macro a @r {
!if @r != 1 { !if @r != 1 {

152
testing/numberflags.a Normal file
View File

@ -0,0 +1,152 @@
;ACME 0.96.5
*=$1000
!cpu 65816 ; we need 24-bit addressing
!macro fitsbyte .arg {
.b
lda .arg
!if * - .b != 2 {
!error "argument wasn't flagged as 'fits byte'"
}
}
!macro defaultsto16b .arg {
.b
lda .arg
!if * - .b != 3 {
!error "argument wasn't flagged as '16 bit size'"
}
}
!macro defaultsto24b .arg {
.b
lda .arg
!if * - .b != 4 {
!error "argument wasn't flagged as '24 bit size'"
}
}
byte = < (label&0) ; now byte should have FITS_BYTE flag
bigger = label & 0 ; and bigger shouldn't
enforce8+1 = label&0 ; enforce8 should enforce 8-bit addressing
enforce16+2 = label&0 ; enforce16 should enforce 16-bit addressing
enforce24+3 = label&0 ; enforce24 should enforce 24-bit addressing
; check all monadics
+fitsbyte byte
+defaultsto16b bigger
+fitsbyte enforce8
+defaultsto16b enforce16
+defaultsto24b enforce24
+defaultsto16b NOT byte
+defaultsto16b NOT bigger
+fitsbyte NOT enforce8
+defaultsto16b NOT enforce16
+defaultsto24b NOT enforce24
+defaultsto16b -byte
+defaultsto16b -bigger
+fitsbyte -enforce8
+defaultsto16b -enforce16
+defaultsto24b -enforce24
+fitsbyte <byte
+fitsbyte <bigger
+fitsbyte <enforce8
+fitsbyte <enforce16
+fitsbyte <enforce24
+fitsbyte >byte
+fitsbyte >bigger
+fitsbyte >enforce8
+fitsbyte >enforce16
+fitsbyte >enforce24
+fitsbyte ^byte
+fitsbyte ^bigger
+fitsbyte ^enforce8
+fitsbyte ^enforce16
+fitsbyte ^enforce24
+fitsbyte address(byte)
+defaultsto16b address(bigger)
+fitsbyte address(enforce8)
+defaultsto16b address(enforce16)
+defaultsto24b address(enforce24)
+fitsbyte int(byte)
+defaultsto16b int(bigger)
+fitsbyte int(enforce8)
+defaultsto16b int(enforce16)
+defaultsto24b int(enforce24)
+fitsbyte float(byte)
+defaultsto16b float(bigger)
+fitsbyte float(enforce8)
+defaultsto16b float(enforce16)
+defaultsto24b float(enforce24)
+defaultsto16b sin(byte)
+defaultsto16b sin(bigger)
+fitsbyte sin(enforce8)
+defaultsto16b sin(enforce16)
+defaultsto24b sin(enforce24)
+defaultsto16b cos(byte)
+defaultsto16b cos(bigger)
+fitsbyte cos(enforce8)
+defaultsto16b cos(enforce16)
+defaultsto24b cos(enforce24)
+defaultsto16b tan(byte)
+defaultsto16b tan(bigger)
+fitsbyte tan(enforce8)
+defaultsto16b tan(enforce16)
+defaultsto24b tan(enforce24)
+defaultsto16b arcsin(byte)
+defaultsto16b arcsin(bigger)
+fitsbyte arcsin(enforce8)
+defaultsto16b arcsin(enforce16)
+defaultsto24b arcsin(enforce24)
+defaultsto16b arccos(byte)
+defaultsto16b arccos(bigger)
+fitsbyte arccos(enforce8)
+defaultsto16b arccos(enforce16)
+defaultsto24b arccos(enforce24)
+defaultsto16b arctan(byte)
+defaultsto16b arctan(bigger)
+fitsbyte arctan(enforce8)
+defaultsto16b arctan(enforce16)
+defaultsto24b arctan(enforce24)
+fitsbyte 'a'
+fitsbyte <label
+fitsbyte >label
+fitsbyte ^label
+fitsbyte label < label
+fitsbyte label <= label
+fitsbyte label > label
+fitsbyte label >= label
+fitsbyte label = label
+fitsbyte label != label
+fitsbyte enforce16 < enforce24
+fitsbyte enforce16 <= enforce24
+fitsbyte enforce16 > enforce24
+fitsbyte enforce16 >= enforce24
+fitsbyte enforce16 = enforce24
+fitsbyte enforce16 != enforce24
+fitsbyte $ff
+defaultsto16b $0ff
+defaultsto16b $0ff
+defaultsto24b $000ff
+fitsbyte %########
+defaultsto16b %.########
+defaultsto24b %.........########
+fitsbyte &377
+defaultsto16b &0377
+defaultsto24b &0000377
+defaultsto16b label
other = label
+defaultsto16b other
label