--- a/SmallInt.st Fri Jul 16 11:39:45 1993 +0200
+++ b/SmallInt.st Mon Oct 04 11:32:33 1993 +0100
@@ -59,6 +59,8 @@
%{ /* NOCONTEXT */
RETURN ( _MKSMALLINT(N_INT_BITS) );
%}
+
+ "SmallInteger maxBits"
!
maxBytes
@@ -67,6 +69,8 @@
%{ /* NOCONTEXT */
RETURN ( _MKSMALLINT(N_INT_BITS / 8 + 1) );
%}
+
+ "SmallInteger maxBytes"
!
minVal
@@ -75,6 +79,8 @@
%{ /* NOCONTEXT */
RETURN ( _MKSMALLINT(_MIN_INT) );
%}
+
+ "SmallInteger minVal"
!
maxVal
@@ -83,6 +89,8 @@
%{ /* NOCONTEXT */
RETURN ( _MKSMALLINT(_MAX_INT) );
%}
+
+ "SmallInteger maxVal"
! !
!SmallInteger methodsFor:'error catching'!
@@ -133,14 +141,14 @@
shallowCopy
"return a shallow copy of myself
- - reimplemented here since numbers are unique"
+ - reimplemented here since smallintegers are unique"
^ self
!
deepCopy
"return a deep copy of myself
- - reimplemented here since numbers are unique"
+ - reimplemented here since smallintegers are unique"
^ self
! !
@@ -412,9 +420,9 @@
%{ /* NOCONTEXT */
if (_isSmallInteger(min) && _isSmallInteger(max)) {
- REGISTER INT selfVal;
+ REGISTER INT selfVal;
- selfVal = _intVal(self);
+ selfVal = _intVal(self);
if (selfVal < _intVal(min)) {
RETURN ( false );
}
@@ -465,24 +473,24 @@
if (_isSmallInteger(aNumber)) {
#ifdef _ADD_IO_IO
- RETURN ( _ADD_IO_IO(self, aNumber) );
+ RETURN ( _ADD_IO_IO(self, aNumber) );
#else
REGISTER INT sum;
- extern OBJ _makeLarge();
+ extern OBJ _makeLarge();
sum = _intVal(self) + _intVal(aNumber);
if ((sum >= _MIN_INT) && (sum <= _MAX_INT)) {
RETURN ( _MKSMALLINT(sum) );
}
- RETURN ( _makeLarge(sum) );
+ RETURN ( _makeLarge(sum) );
#endif
}
if ((aNumber != nil) && (_qClass(aNumber) == Float)) {
extern char *newNextPtr, *newEndPtr;
OBJ newFloat;
- double val;
+ double val;
- val = _floatVal(aNumber);
+ val = _floatVal(aNumber);
_qAlignedNew(newFloat, sizeof(struct floatstruct), SENDER);
_InstPtr(newFloat)->o_class = Float;
_FloatInstPtr(newFloat)->f_floatvalue = (double)(_intVal(self)) + val;
@@ -500,24 +508,24 @@
if (_isSmallInteger(aNumber)) {
#ifdef _SUB_IO_IO
- RETURN ( _SUB_IO_IO(self, aNumber) );
+ RETURN ( _SUB_IO_IO(self, aNumber) );
#else
REGISTER INT diff;
- extern OBJ _makeLarge();
+ extern OBJ _makeLarge();
diff = _intVal(self) - _intVal(aNumber);
if ((diff >= _MIN_INT) && (diff <= _MAX_INT)) {
RETURN ( _MKSMALLINT(diff) );
}
- RETURN ( _makeLarge(diff) );
+ RETURN ( _makeLarge(diff) );
#endif
}
if ((aNumber != nil) && (_qClass(aNumber) == Float)) {
extern char *newNextPtr, *newEndPtr;
OBJ newFloat;
- double val;
+ double val;
- val = _floatVal(aNumber);
+ val = _floatVal(aNumber);
_qAlignedNew(newFloat, sizeof(struct floatstruct), SENDER);
_InstPtr(newFloat)->o_class = Float;
_FloatInstPtr(newFloat)->f_floatvalue = (double)(_intVal(self)) - val;
@@ -562,9 +570,9 @@
} else if ((aNumber != nil) && (_qClass(aNumber) == Float)) {
extern char *newNextPtr, *newEndPtr;
OBJ newFloat;
- double val;
+ double val;
- val = _floatVal(aNumber);
+ val = _floatVal(aNumber);
_qAlignedNew(newFloat, sizeof(struct floatstruct), SENDER);
_InstPtr(newFloat)->o_class = Float;
_FloatInstPtr(newFloat)->f_floatvalue = (double)(_intVal(self)) * val;
@@ -634,7 +642,7 @@
me = _intVal(self);
RETURN ( _MKFLOAT((double)me / dval COMMA_CON) );
}
- }
+ }
}
%}
.
@@ -648,39 +656,54 @@
^ aNumber quotientFromInteger:self
!
-// anInteger
+// aNumber
"return the integer part of the quotient of the receivers value
and the arguments value"
%{ /* NOCONTEXT */
INT val;
- if (_isSmallInteger(anInteger)) {
- val = _intVal(anInteger);
+ if (_isSmallInteger(aNumber)) {
+ val = _intVal(aNumber);
if (val != 0) {
RETURN ( _MKSMALLINT(_intVal(self) / val) );
}
+ } else {
+ if (_isFraction(aNumber)) {
+ OBJ t;
+ INT num, den;
+
+ t = _FractionInstPtr(aNumber)->f_numerator;
+ if (_isSmallInteger(t)) {
+ num = _intVal(t);
+ t = _FractionInstPtr(aNumber)->f_denominator;
+ if (_isSmallInteger(t)) {
+ den = _intVal(t);
+ RETURN ( _MKSMALLINT(_intVal(self) * den / num ));
+ }
+ }
+ }
}
%}
.
- (anInteger = 0) ifTrue:[
+ (aNumber = 0) ifTrue:[
DivisionByZeroSignal raise.
^ self
].
- ^ self retry:#// coercing:anInteger
+ ^ self retry:#// coercing:aNumber
!
-\\ anInteger
+\\ aNumber
"return the integer rest of the receivers value
divided by the arguments value"
%{ /* NOCONTEXT */
INT mySelf, val;
- if (_isSmallInteger(anInteger)) {
+ if (_isSmallInteger(aNumber)) {
mySelf = _intVal(self);
if (mySelf < 0) mySelf = -mySelf;
- val = _intVal(anInteger);
+ val = _intVal(aNumber);
if (val != 0) {
if (val < 0) {
RETURN ( _MKSMALLINT(-(mySelf % -val)) );
@@ -690,11 +713,11 @@
}
%}
.
- (anInteger = 0) ifTrue:[
+ (aNumber = 0) ifTrue:[
DivisionByZeroSignal raise.
^ self
].
- ^ self retry:#\\ coercing:anInteger
+ ^ self retry:#\\ coercing:aNumber
!
abs
@@ -1014,25 +1037,25 @@
INT orgArg, ttt, selfInt, temp;
ttt = orgArg = _intVal(anInteger);
- if (ttt) {
+ if (ttt) {
selfInt = _intVal(self);
while (ttt != 0) {
temp = selfInt % ttt;
selfInt = ttt;
ttt = temp;
}
- /*
- * since its not defined in what the sign of
- * a modulu result is when the arg is negative,
- * change it explicitely here ...
- */
- if (orgArg < 0) {
- /* result should be negative */
+ /*
+ * since its not defined in what the sign of
+ * a modulu result is when the arg is negative,
+ * change it explicitely here ...
+ */
+ if (orgArg < 0) {
+ /* result should be negative */
if (selfInt > 0) selfInt = -selfInt;
- } else {
- /* result should be positive */
- if (selfInt < 0) selfInt = -selfInt;
- }
+ } else {
+ /* result should be positive */
+ if (selfInt < 0) selfInt = -selfInt;
+ }
RETURN ( _MKSMALLINT(selfInt) );
}
}
@@ -1121,8 +1144,8 @@
REGISTER OBJFUNC code;
extern OBJ Block, _value_;
static struct inlineCache blockVal = _ILC1;
+ REGISTER OBJ rHome;
#ifdef UPDATE_WHOLE_STACK
- REGISTER OBJ rHome;
# undef home
# define home rHome
#endif
@@ -1130,37 +1153,58 @@
if (_isSmallInteger(stop)) {
tmp = _intVal(self);
final = _intVal(stop);
- if (_isBlock(aBlock)
+ if (__isBlock(aBlock)
&& ((code = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
&& (_BlockInstPtr(aBlock)->b_nargs == _MKSMALLINT(1))) {
/*
- * arg is a compiled block -
+ * arg is a compiled block -
* directly call it without going through "Block-value"
*/
home = _BlockInstPtr(aBlock)->b_home;
- while (tmp <= final) {
- if (InterruptPending != nil) interrupt(CONARG);
+#ifndef UPDATE_WHOLE_STACK
+ rHome = home;
+ if ((rHome == nil) || (_qSpace(rHome) >= STACKSPACE)) {
+ /*
+ * home will not move - keep in in a register
+ */
+ while (tmp <= final) {
+ if (InterruptPending != nil) interrupt(CONARG);
+# ifdef PASS_ARG_REF
+ index = _MKSMALLINT(tmp);
+ (*code)(rHome, CON_COMMA &index);
+# else
+ (*code)(rHome, CON_COMMA _MKSMALLINT(tmp));
+# endif
+ tmp++;
+ }
+ } else
+#endif
+ {
+ while (tmp <= final) {
+ if (InterruptPending != nil) interrupt(CONARG);
- index = _MKSMALLINT(tmp);
#ifdef PASS_ARG_REF
- (*code)(home, CON_COMMA &index);
+ index = _MKSMALLINT(tmp);
+ (*code)(home, CON_COMMA &index);
#else
- (*code)(home, CON_COMMA index);
+ (*code)(home, CON_COMMA _MKSMALLINT(tmp));
#endif
- tmp++;
+ tmp++;
+ }
}
} else {
/*
- * arg is something else - call it with Block-value"
+ * arg is something else - call it with Block-value"
*/
while (tmp <= final) {
if (InterruptPending != nil) interrupt(CONARG);
+#ifdef PASS_ARG_REF
index = _MKSMALLINT(tmp);
-#ifdef PASS_ARG_REF
(*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal, &index);
#else
- (*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal, index);
+ (*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal,
+ _MKSMALLINT(tmp));
#endif
tmp++;
}
@@ -1182,8 +1226,8 @@
REGISTER OBJFUNC code;
extern OBJ Block, _value_;
static struct inlineCache blockVal = _ILC1;
+ REGISTER OBJ rHome;
#ifdef UPDATE_WHOLE_STACK
- REGISTER OBJ rHome;
# undef home
# define home rHome
#endif
@@ -1193,74 +1237,144 @@
tmp = _intVal(self);
final = _intVal(stop);
step = _intVal(incr);
- if (_isBlock(aBlock)
+ if (__isBlock(aBlock)
&& ((code = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
&& (_BlockInstPtr(aBlock)->b_nargs == _MKSMALLINT(1))) {
/*
- * arg is a compiled block -
+ * arg is a compiled block -
* directly call it without going through "Block-value"
*/
home = _BlockInstPtr(aBlock)->b_home;
- if (step < 0) {
+ if (step < 0) {
+#ifndef UPDATE_WHOLE_STACK
+ rHome = home;
+ if ((rHome == nil) || (_qSpace(rHome) >= STACKSPACE)) {
+ while (tmp >= final) {
+ if (InterruptPending != nil) interrupt(CONARG);
+
+# ifdef PASS_ARG_REF
+ index = _MKSMALLINT(tmp);
+ (*code)(rHome, CON_COMMA &index);
+# else
+ (*code)(rHome, CON_COMMA _MKSMALLINT(tmp));
+# endif
+ tmp += step;
+ }
+ } else
+#endif
+ {
+ while (tmp >= final) {
+ if (InterruptPending != nil) interrupt(CONARG);
+
+#ifdef PASS_ARG_REF
+ index = _MKSMALLINT(tmp);
+ (*code)(home, CON_COMMA &index);
+#else
+ (*code)(home, CON_COMMA _MKSMALLINT(tmp));
+#endif
+ tmp += step;
+ }
+ }
+ } else {
+#ifndef UPDATE_WHOLE_STACK
+ rHome = home;
+ if ((rHome == nil) || (_qSpace(rHome) >= STACKSPACE)) {
+ while (tmp <= final) {
+ if (InterruptPending != nil) interrupt(CONARG);
+
+# ifdef PASS_ARG_REF
+ index = _MKSMALLINT(tmp);
+ (*code)(rHome, CON_COMMA &index);
+# else
+ (*code)(rHome, CON_COMMA _MKSMALLINT(tmp));
+# endif
+ tmp += step;
+ }
+ } else
+#endif
+ {
+ while (tmp <= final) {
+ if (InterruptPending != nil) interrupt(CONARG);
+
+#ifdef PASS_ARG_REF
+ index = _MKSMALLINT(tmp);
+ (*code)(home, CON_COMMA &index);
+#else
+ (*code)(home, CON_COMMA _MKSMALLINT(tmp));
+#endif
+ tmp += step;
+ }
+ }
+ }
+ } else {
+ /*
+ * arg is something else - call it with Block-value"
+ */
+ if (step < 0) {
while (tmp >= final) {
if (InterruptPending != nil) interrupt(CONARG);
+#ifdef PASS_ARG_REF
index = _MKSMALLINT(tmp);
-#ifdef PASS_ARG_REF
- (*code)(home, CON_COMMA &index);
+ (*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal, &index);
#else
- (*code)(home, CON_COMMA index);
+ (*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal,
+ _MKSMALLINT(tmp));
#endif
tmp += step;
}
- } else {
+ } else {
while (tmp <= final) {
if (InterruptPending != nil) interrupt(CONARG);
+#ifdef PASS_ARG_REF
index = _MKSMALLINT(tmp);
-#ifdef PASS_ARG_REF
- (*code)(home, CON_COMMA &index);
+ (*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal, &index);
#else
- (*code)(home, CON_COMMA index);
+ (*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal,
+ _MKSMALLINT(tmp));
#endif
tmp += step;
}
}
- } else {
- /*
- * arg is something else - call it with Block-value"
- */
- if (step < 0) {
- while (tmp >= final) {
- if (InterruptPending != nil) interrupt(CONARG);
-
- index = _MKSMALLINT(tmp);
-#ifdef PASS_ARG_REF
- (*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal, &index);
-#else
- (*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal, index);
-#endif
- tmp += step;
- }
- } else {
- while (tmp <= final) {
- if (InterruptPending != nil) interrupt(CONARG);
-
- index = _MKSMALLINT(tmp);
-#ifdef PASS_ARG_REF
- (*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal, &index);
-#else
- (*blockVal.ilc_func)(aBlock, _value_, CON_COMMA nil, &blockVal, index);
-#endif
- tmp += step;
- }
- }
}
RETURN ( self );
}
%}
.
- ^super to:stop do:aBlock
+ ^ super to:stop do:aBlock
+! !
+
+!SmallInteger class methodsFor:'binary storage'!
+
+binaryDefinitionFrom: stream manager: manager
+ "read the binary representation as stored in storeBinaryOn:"
+
+ | value |
+
+ value := stream next bitAnd: 16r7F.
+ value > 16r3F ifTrue: [
+ value := value - 16r80
+ ].
+ value := (value bitShift: 8) bitOr: stream next.
+ value := (value bitShift: 8) bitOr: stream next.
+ value := (value bitShift: 8) bitOr: stream next.
+ ^ value
+! !
+
+!SmallInteger methodsFor:'binary storage'!
+
+hasSpecialBinaryRepresentation
+ ^ true
+!
+
+storeBinaryOn: stream manager: manager
+ "SmallIntegers are stored as their value with the 32nd bit set as a tag."
+
+ stream nextPut: (((self bitShift: -24) bitAnd: 16rFF) bitOr: 16r80).
+ stream nextPut: ((self bitShift: -16) bitAnd: 16rFF).
+ stream nextPut: ((self bitShift: -8) bitAnd: 16rFF).
+ stream nextPut: (self bitAnd: 16rFF)
! !
!SmallInteger methodsFor:'printing & storing'!
@@ -1300,16 +1414,16 @@
if (_isSmallInteger(radix)) {
switch (_intVal(radix)) {
- case 10:
- format = "%d";
- break;
- case 16:
- format = "%x";
- break;
- case 8:
- format = "%o";
- break;
- }
+ case 10:
+ format = "%d";
+ break;
+ case 16:
+ format = "%x";
+ break;
+ case 8:
+ format = "%o";
+ break;
+ }
}
if (format) {