moo/moo/kernel/Magnitu.moo

405 lines
6.0 KiB
Smalltalk
Raw Normal View History

2017-01-06 13:30:02 +00:00
class Magnitude(Object)
{
method < aMagnitude { self subclassResponsibility: #< }
method > aMagnitude { ^aMagnitude < self }
method <= aMagnitude { ^(aMagnitude < self) not }
method >= aMagnitude { ^(self < aMagnitude) not }
method between: min and: max
{
^self >= min and self <= max
}
method min: aMagnitude
{
##^self < aMagnitude ifTrue: [self] ifFalse: [aMagnitude]
^if (self < aMagnitude) { self } else { aMagnitude }.
}
method max: aMagnitude
{
##^self > aMagnitude ifTrue: [self] ifFalse: [aMagnitude]
^if (self > aMagnitude) { self } else { aMagnitude }.
}
2017-01-06 13:30:02 +00:00
}
class Association(Magnitude)
{
var key, value.
2017-01-06 13:30:02 +00:00
method(#class) key: key value: value
{
^self new key: key value: value
}
2017-01-06 13:30:02 +00:00
method key: key value: value
{
self.key := key.
self.value := value.
}
method value: value
{
self.value := value
}
2017-01-06 13:30:02 +00:00
method key
{
^self.key
}
method value
{
^self.value
}
2017-01-06 13:30:02 +00:00
method = ass
{
^(self.key = ass key) and (self.value = ass value)
2017-01-06 13:30:02 +00:00
}
2017-01-06 13:30:02 +00:00
method hash
{
^(self.key hash) + (self.value hash)
}
}
class(#limited) Character(Magnitude)
2017-01-06 13:30:02 +00:00
{
## method(#primitive,#class) codePoint: code.
## method(#primitive) codePoint.
method asCharacter { ^self }
method(#primitive) asError.
method(#primitive) asInteger.
method(#primitive) < char.
method(#primitive) > char.
method(#primitive) <= char.
method(#primitive) >= char.
method digitValue: anInteger
{
^'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' at: anInteger
}
method digitValue
{
##<primitive: #Character_digitValue>
if ((self >= $0) and (self <= $9))
{
^self asInteger - $0 asInteger
}
elsif ((self >= $A) and (self <= $Z))
{
^self asInteger - $A asInteger + 10
}
elsif ((self >= $a) and (self <= $z))
{
^self asInteger - $a asInteger + 10
}.
##Exception signal: 'not a digit character'.
^-1
}
2017-01-06 13:30:02 +00:00
}
class(#limited) Number(Magnitude)
2017-01-06 13:30:02 +00:00
{
method + aNumber
{
<primitive: #_number_add>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method - aNumber
{
<primitive: #_number_sub>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method * aNumber
{
<primitive: #_number_mul>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method mul: aNumber
{
<primitive: #_number_mul>
self primitiveFailed.
}
method mlt: aNumber
{
<primitive: #_number_mlt>
self primitiveFailed.
}
method div: aNumber
2017-01-06 13:30:02 +00:00
{
## integer division rounded toward zero
<primitive: #_number_div>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method rem: aNumber
{
## integer remainder rounded toward zero
2017-01-06 13:30:02 +00:00
<primitive: #_integer_rem>
self primitiveFailed.
}
method mdiv: aNumber
2017-01-06 13:30:02 +00:00
{
## integer division quotient
2019-01-10 07:00:17 +00:00
<primitive: #_number_mdiv>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method mod: aNumber
2017-01-06 13:30:02 +00:00
{
## integer division remainder
<primitive: #_integer_mod>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
##method / aNumber
##{
## ## fraction? fixed-point decimal? floating-point?
##}
2017-01-06 13:30:02 +00:00
method = aNumber
{
<primitive: #_number_eq>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method ~= aNumber
{
<primitive: #_number_ne>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method < aNumber
{
2019-01-10 07:00:17 +00:00
<primitive: #_number_lt>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method > aNumber
{
2019-01-10 07:00:17 +00:00
<primitive: #_number_gt>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method <= aNumber
{
2019-01-10 07:00:17 +00:00
<primitive: #_number_le>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method >= aNumber
{
2019-01-10 07:00:17 +00:00
<primitive: #_number_ge>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
method negated
{
2019-01-10 07:00:17 +00:00
<primitive: #_number_negated>
2017-01-06 13:30:02 +00:00
^0 - self.
}
method bitAt: index
{
<primitive: #_integer_bitat>
^(self bitShift: index negated) bitAnd: 1.
}
method bitAnd: aNumber
{
<primitive: #_integer_bitand>
self primitiveFailed.
}
method bitOr: aNumber
{
<primitive: #_integer_bitor>
self primitiveFailed.
}
method bitXor: aNumber
{
<primitive: #_integer_bitxor>
self primitiveFailed.
}
method bitInvert
{
<primitive: #_integer_bitinv>
^-1 - self.
}
method bitShift: aNumber
{
(* positive number for left shift.
* negative number for right shift *)
<primitive: #_integer_bitshift>
self primitiveFailed.
}
method asString
{
^self printStringRadix: 10
}
method printStringRadix: aNumber
{
2019-01-10 10:01:50 +00:00
<primitive: #_number_numtostr>
2017-01-06 13:30:02 +00:00
self primitiveFailed.
}
2017-03-04 05:48:23 +00:00
method to: end by: step do: block
2017-01-06 13:30:02 +00:00
{
| i |
i := self.
2017-03-04 05:48:23 +00:00
(*
2017-01-06 13:30:02 +00:00
(step > 0)
ifTrue: [
[ i <= end ] whileTrue: [
2017-03-04 05:48:23 +00:00
block value: i.
2017-01-06 13:30:02 +00:00
i := i + step.
].
]
ifFalse: [
[ i >= end ] whileTrue: [
2017-03-04 05:48:23 +00:00
block value: i.
2017-01-06 13:30:02 +00:00
i := i - step.
].
].
2017-03-04 05:48:23 +00:00
*)
if (step > 0)
{
while (i <= end)
{
block value: i.
i := i + step.
}
}
else
{
while ( i => end)
{
block value: i.
i := i - step.
}
}
}
method to: end do: block
{
^self to: end by: 1 do: block.
2017-01-06 13:30:02 +00:00
}
2017-03-04 05:48:23 +00:00
method priorTo: end by: step do: block
2017-01-06 13:30:02 +00:00
{
| i |
i := self.
2017-03-04 05:48:23 +00:00
(*
2017-01-06 13:30:02 +00:00
(step > 0)
ifTrue: [
[ i < end ] whileTrue: [
2017-03-04 05:48:23 +00:00
block value: i.
2017-01-06 13:30:02 +00:00
i := i + step.
].
]
ifFalse: [
[ i > end ] whileTrue: [
2017-03-04 05:48:23 +00:00
block value: i.
2017-01-06 13:30:02 +00:00
i := i - step.
].
].
2017-03-04 05:48:23 +00:00
*)
if (step > 0)
{
while (i < end)
{
block value: i.
i := i + step.
}
}
else
{
while ( i > end)
{
block value: i.
i := i - step.
}
}
2017-01-06 13:30:02 +00:00
}
2017-03-04 05:48:23 +00:00
method priorTo: end do: block
2017-01-06 13:30:02 +00:00
{
2017-03-04 05:48:23 +00:00
^self priorTo: end by: 1 do: block.
2017-01-06 13:30:02 +00:00
}
method abs
{
2017-03-04 05:48:23 +00:00
(*self < 0 ifTrue: [^self negated].
^self.*)
^if (self < 0) { self negated } else { self }
2017-01-06 13:30:02 +00:00
}
method sign
{
2017-03-04 05:48:23 +00:00
(* self < 0 ifTrue: [^-1].
2017-01-06 13:30:02 +00:00
self > 0 ifTrue: [^1].
2017-03-04 05:48:23 +00:00
^0.*)
2017-05-07 14:45:27 +00:00
^if (self < 0) { -1 } elsif (self > 0) { 1 } else { 0 }
2017-01-06 13:30:02 +00:00
}
}
class(#limited) Integer(Number)
2017-01-06 13:30:02 +00:00
{
method timesRepeat: aBlock
{
2017-05-07 14:45:27 +00:00
## 1 to: self by: 1 do: [ :count | aBlock value ].
| count |
count := 0.
while (count < self) { aBlock value. count := count + 1 }
2017-01-06 13:30:02 +00:00
}
method asInteger { ^self }
2017-01-06 13:30:02 +00:00
}
class(#limited) SmallInteger(Integer)
2017-01-06 13:30:02 +00:00
{
method(#primitive) asCharacter.
2017-05-07 14:45:27 +00:00
method(#primitive) asError.
2017-01-06 13:30:02 +00:00
}
2019-01-01 06:44:28 +00:00
class(#limited,#immutable,#liword) LargeInteger(Integer)
2017-01-06 13:30:02 +00:00
{
}
2019-01-01 06:44:28 +00:00
class(#limited,#immutable,#liword) LargePositiveInteger(LargeInteger)
2017-01-06 13:30:02 +00:00
{
2017-03-04 05:48:23 +00:00
method abs { ^self }
method sign { ^1 }
2017-01-06 13:30:02 +00:00
}
2019-01-01 06:44:28 +00:00
class(#limited,#immutable,#liword) LargeNegativeInteger(LargeInteger)
2017-01-06 13:30:02 +00:00
{
2017-03-04 05:48:23 +00:00
method abs { ^self negated }
method sign { ^-1 }
2017-01-06 13:30:02 +00:00
}
2019-01-01 06:44:28 +00:00
class(#limited,#immutable) FixedPointDecimal(Number)
{
var value, scale.
}