diff --git a/modules/Kernel/Float.st b/modules/Kernel/Float.st index abea14f6..9d7dfdb2 100644 --- a/modules/Kernel/Float.st +++ b/modules/Kernel/Float.st @@ -20,7 +20,9 @@ Class { { #category : #private } Float class >> basicErrorOn: aSymbol status: status for: aNumber [ - self error: 'Float error ' , aSymbol + self error: 'Float error ' , aSymbol. + #FloatPlus. #FloatMinus. #FloatMultiply. #FloatDiv. #FloatLess. #FloatEqual. + #FloatFractionPart. #FloatSignificand. #FloatSqrt. #FloatTimesTwoPower. #FloatTruncated "hack to get the symbols interned in kernel" ] { #category : #errors } @@ -61,29 +63,21 @@ Float class >> from: aNumber [ { #category : #'instance creation' } Float class >> fromByteArray: aByteArray [ - | float size | - float := self new. - size := float size. - float - replaceBytesFrom: 1 - to: size - with: aByteArray - startingAt: 1. - ^float + ^self new initializeWith: aByteArray +] + +{ #category : #'instance creation' } +Float class >> fromBytes: anObject [ + | float | + ^anObject isByteArray ifTrue: [self fromByteArray: anObject] ifFalse: [ + float := self new. + float replaceBytesFrom: 1 to: 8 with: anObject startingAt: 1. + ^float] ] { #category : #'instance creation' } Float class >> fromInteger: anInteger [ - | result | - result := Float new. - anInteger _isSmallInteger ifTrue: [ - Float clearStatusFlags. - anInteger _asNative _asFloatInto: result. - ^result]. - anInteger isInteger - ifTrue: [^(self fromInteger: (anInteger bitShift: -24)) * 16r1000000 asFloat - + (self fromInteger: (anInteger bitAnd: 16rFFFFFF))] - ifFalse: [self error: 'number is not an integer'] + ^self errorVMSpecific ] { #category : #'instance creation' } @@ -133,7 +127,7 @@ Float class >> hasDenormalizedOperandFlag: status [ { #category : #testing } Float class >> hasErrorFlag: status [ - ^(status bitAnd: 0x1F) ~= 0 + ^(status bitAnd: 0x1F) != 0 ] { #category : #testing } @@ -357,7 +351,7 @@ Float class >> statusVar [ { #category : #'instance creation' } Float class >> usingBytes: aByteArray [ - ^self fromByteArray: aByteArray + ^self new initializeWith: aByteArray ] { #category : #constants } @@ -367,44 +361,17 @@ Float class >> zero [ { #category : #arithmetic } Float >> - aNumber [ - | result status | - aNumber isFloat ifFalse: [^self - aNumber asFloat]. - result := Float new. - Float clearStatusFlags. - self _floatMinus: aNumber into: result. - status := Float status. - (Float hasErrorFlag: status) ifFalse: [^result]. - ^(Float hasDenormalizedOperandFlag: status) - ifTrue: [self asNormalized - aNumber asNormalized] - ifFalse: [self errorOn: #'-' status: status] + ^self errorVMSpecific ] { #category : #arithmetic } Float >> * aNumber [ - | result status | - aNumber isFloat ifFalse: [^self * aNumber asFloat]. - result := Float new. - Float clearStatusFlags. - self _floatMultiply: aNumber into: result. - status := Float status. - (Float hasErrorFlag: status) ifFalse: [^result]. - ^(Float hasDenormalizedOperandFlag: status) - ifTrue: [self asNormalized * aNumber asNormalized] - ifFalse: [self errorOn: #'*' status: status] + ^self errorVMSpecific ] { #category : #arithmetic } Float >> / aNumber [ - | result status | - aNumber isFloat ifFalse: [^self / aNumber asFloat]. - result := Float new. - Float clearStatusFlags. - self _floatQuotient: aNumber into: result. - status := Float status. - (Float hasErrorFlag: status) ifFalse: [^result]. - ^(Float hasDenormalizedOperandFlag: status) - ifTrue: [self asNormalized / aNumber asNormalized] - ifFalse: [self errorOn: #'/' status: status] + ^self errorVMSpecific ] { #category : #arithmetic } @@ -432,29 +399,12 @@ Float >> ~ aFloat [ { #category : #arithmetic } Float >> + aNumber [ - | result status | - aNumber isFloat ifFalse: [^aNumber addTo: self]. - result := Float new. - Float clearStatusFlags. - self _floatPlus: aNumber into: result. - status := Float status. - (Float hasErrorFlag: status) ifFalse: [^result]. - ^(Float hasDenormalizedOperandFlag: status) - ifTrue: [self asNormalized + aNumber asNormalized] - ifFalse: [self errorOn: #'+' status: status] + ^self errorVMSpecific ] { #category : #comparing } Float >> < aNumber [ - | result status | - aNumber isFloat ifFalse: [^self < aNumber asFloat]. - Float clearStatusFlags. - result := 0 == (self _floatLessThan: aNumber). - status := Float status. - (Float hasErrorFlag: status) ifFalse: [^result]. - (Float hasDenormalizedOperandFlag: status) ifTrue: [^result]. - (self isSpecialValue or: [aNumber isSpecialValue]) ifTrue: [^result]. - self errorOn: #'<' status: status + ^self errorVMSpecific ] { #category : #comparing } @@ -471,21 +421,7 @@ Float >> <= aNumber [ { #category : #comparing } Float >> = aNumber [ - | result status nan equal | - aNumber isFloat - ifFalse: [^aNumber isNumber - ifTrue: [self = aNumber asFloat] - ifFalse: [false]]. - Float clearStatusFlags. - result := 0 == (self _floatEquals: aNumber). - status := Float status. - (Float hasErrorFlag: status) ifFalse: [^result]. - (Float hasDenormalizedOperandFlag: status) ifTrue: [^result]. - nan := self isNaN. - equal := nan == aNumber isNaN. - equal ifFalse: [^false]. - nan ifTrue: [^true]. - self errorOn: #'=' status: status + ^self errorVMSpecific ] { #category : #comparing } @@ -571,6 +507,16 @@ Float >> asTrueFraction [ ^numerator / denominator ] +{ #category : #testing } +Float >> at: index [ + ^self errorVMSpecific +] + +{ #category : #testing } +Float >> basicAt: index [ + ^self errorVMSpecific +] + { #category : #arithmetic } Float >> ceiling [ ^self isNaN ifTrue: [self] ifFalse: [super ceiling] @@ -591,6 +537,11 @@ Float >> degreesToRadians [ ^self * RadiansPerDegree ] +{ #category : #random } +Float >> errorOn: aSymbol [ + ^self errorVMSpecific +] + { #category : #errors } Float >> errorOn: aSymbol status: anInteger [ ^self class errorOn: aSymbol status: anInteger for: self @@ -618,15 +569,7 @@ Float >> floor [ { #category : #random } Float >> fractionPart [ - | fraction status | - fraction := Float new. - Float clearStatusFlags. - self _floatFractionPartInto: fraction. - status := Float status. - (Float hasErrorFlag: status) ifFalse: [^fraction]. - ^(Float hasDenormalizedOperandFlag: status) - ifTrue: [self asNormalized fractionPart] - ifFalse: [self errorOn: #fractionPart status: status] + ^self errorVMSpecific ] { #category : #testing } @@ -668,6 +611,11 @@ Float >> hasZeroMantissa [ ^(self at: 1) = 0 ] +{ #category : #random } +Float >> initializeWith: bytes [ + self errorVMSpecific +] + { #category : #testing } Float >> isDenormalizedValue [ ^self hasZeroExponent and: [self hasZeroMantissa not] @@ -859,11 +807,7 @@ Float >> sign [ { #category : #accessing } Float >> significand [ - | status | - status := Float status. - ^(Float hasDenormalizedOperandFlag: status) - ifTrue: [self asNormalized significand] - ifFalse: [self errorOn: #significand status: status] + ^self errorVMSpecific ] { #category : #trigonometry } @@ -878,15 +822,7 @@ Float >> sizeInBytes [ { #category : #functions } Float >> sqrt [ - | result status | - result := Float new. - Float clearStatusFlags. - self _floatSqrtInto: result. - status := Float status. - (Float hasErrorFlag: status) ifFalse: [^result]. - ^(Float hasDenormalizedOperandFlag: status) - ifTrue: [self asNormalized sqrt] - ifFalse: [self errorOn: #sqrt status: status] + ^self errorVMSpecific ] { #category : #printing } @@ -901,31 +837,12 @@ Float >> tan [ { #category : #arithmetic } Float >> timesTwoPower: anInteger [ - | result status | - result := self copy. - result _timesTwoPower: anInteger asFloat. - status := Float status. - (Float hasErrorFlag: status) ifFalse: [^result]. - self errorOn: #timesTwoPower status: status + ^self errorVMSpecific ] { #category : #arithmetic } Float >> truncated [ - | result status | - Float clearStatusFlags. - result := self _floatTruncated. - status := Float status. - ((Float hasErrorFlag: status) not - and: [result = 0 or: [result sign = self sign]]) - ifTrue: [^result]. - self isSpecialValue ifTrue: [^self]. - ^self abs < 2.0e16 - ifTrue: [| q r | - q := self quo: 536870912.0. - "((SmallInteger largestPositive bitShift: -1) + 1) asFloat" - r := self - (q asFloat * 536870912.0). - q * 536870912 + r truncated] - ifFalse: [self asTrueFraction] + ^self errorVMSpecific ] { #category : #private } diff --git a/modules/Kernel/LMR/Float.st b/modules/Kernel/LMR/Float.st index db50dd25..85ad028c 100644 --- a/modules/Kernel/LMR/Float.st +++ b/modules/Kernel/LMR/Float.st @@ -9,8 +9,178 @@ Class { #category : #Kernel } + +{ #category : #'instance creation' } +LMRFloat class >> fromInteger: anInteger [ + | result | + result := Float new. + anInteger _isSmallInteger ifTrue: [ + anInteger _asFloatInto: result. + ^result]. + anInteger isInteger + ifTrue: [^(self fromInteger: (anInteger bitShift: -24)) * 16r1000000 asFloat + + (self fromInteger: (anInteger bitAnd: 16rFFFFFF))] + ifFalse: [self error: 'number is not an integer'] +] + +{ #category : #errors } +LMRFloat class >> initialControlAndStatusFlags [ + " + FIXME: ONLY X64 SUPPORTED FOR NOW + We initialize MXCSR with all sticky bits clean (0-5), all exceptions masked (7-12), + and denormal arguments of operations treated as zero (bit 6). + We don't flush denormal results to zero (bit 15), but should think about it. + " + ^0x1FC0 +] + +{ #category : #initialization } +LMRFloat class >> initializeStatus [ + " + this has to be done fairly early at startup, before + doing any float operation, because float operations + try to use this value, which must be already initialized + to what the OS put in MXCSR (or equivalent) register + " + Status isNil ifTrue: [Status := ByteArray new: 4]. + Status uLongAtOffset: 0 put: self status +] + { #category : #'*instance creation' } LMRFloat class >> new [ ^self memory newArrayedBytes: instanceBehavior size: 8. ] +{ #category : #arithmetic } +LMRFloat >> - aNumber [ + | new result | + aNumber isFloat ifFalse: [^self - aNumber asFloat]. + new := Float new. + result := self _floatMinus: aNumber into: new. + result == new ifTrue: [^result]. + ^self errorOn: #'-' status: result +] + +{ #category : #arithmetic } +LMRFloat >> * aNumber [ + | new result | + aNumber isFloat ifFalse: [^self * aNumber asFloat]. + new := Float new. + result := self _floatMultiply: aNumber into: new. + result == new ifTrue: [^result]. + ^self errorOn: #'*' status: result +] + +{ #category : #arithmetic } +LMRFloat >> / aNumber [ + | new result | + aNumber isFloat ifFalse: [^self / aNumber asFloat]. + new := Float new. + result := self _floatQuotient: aNumber into: new. + result == new ifTrue: [^result]. + ^self errorOn: #'/' status: result +] + +{ #category : #arithmetic } +LMRFloat >> + aNumber [ + | new result | + aNumber isFloat ifFalse: [^aNumber addTo: self]. + new := Float new. + result := self _floatPlus: aNumber into: new. + result == new ifTrue: [^result]. + ^self errorOn: #'+' status: result +] + +{ #category : #comparing } +LMRFloat >> < aNumber [ + | result | + aNumber isFloat ifFalse: [^self < aNumber asFloat]. + result := self _floatLessThan: aNumber. + result _isSmallInteger ifFalse: [^result]. + ^self errorOn: #'<' status: result +] + +{ #category : #comparing } +LMRFloat >> = aNumber [ + | result nan equal | + aNumber isFloat + ifFalse: [^aNumber isNumber + ifTrue: [self = aNumber asFloat] + ifFalse: [false]]. + result := self _floatEquals: aNumber. + result _isSmallInteger ifFalse: [^result]. + nan := self isNaN. + equal := nan == aNumber isNaN. + equal ifFalse: [^false]. + nan ifTrue: [^true]. + ^self errorOn: #'=' status: result +] + +{ #category : #testing } +LMRFloat >> at: index [ + ^self basicByteAt: index +] + +{ #category : #testing } +LMRFloat >> basicAt: index [ + ^self basicByteAt: index +] + +{ #category : #random } +LMRFloat >> fractionPart [ + | new result |> + new := Float new. + result := self _floatFractionPartInto: new. + result == new ifTrue: [^result]. + ^self errorOn: #fractionPart status: result +] + +{ #category : #random } +Float >> initializeWith: bytes [ + bytes _primitiveULargeAtOffset: 0 into: self +] + +{ #category : #accessing } +LMRFloat >> significand [ + | result new | + new := Float new. + result := self _floatSignificandInto: new. + result == new ifTrue: [^result]. + ^self errorOn: #significand status: result +] + +{ #category : #functions } +LMRFloat >> sqrt [ + | sqrt result | + sqrt := Float new. + result := self _floatSqrtInto: sqrt. + "_floatSqrtInto returns error status in result if any, else the result itself" + result == sqrt ifTrue: [^result]. + ^self errorOn: #sqrt status: result +] + +{ #category : #arithmetic } +LMRFloat >> timesTwoPower: anInteger [ + | result status | + result := self copy. + status := result _timesTwoPower: anInteger asFloat. + (Float hasErrorFlag: status) ifFalse: [^result]. + self errorOn: #timesTwoPower status: status +] + +{ #category : #arithmetic } +LMRFloat >> truncated [ + | result | + result := self _floatTruncated. + (result notNil and: [result = 0 or: [result sign = self sign]]) + ifTrue: [^result]. + self isSpecialValue ifTrue: [^self]. + ^self abs < 2.0e16 + ifTrue: [| q r | + q := self quo: 536870912.0. + "((SmallInteger largestPositive bitShift: -1) + 1) asFloat" + r := self - (q asFloat * 536870912.0). + q * 536870912 + r truncated] + ifFalse: [self asTrueFraction] +] + diff --git a/modules/Kernel/VM/Float.st b/modules/Kernel/VM/Float.st index 590cd295..1fb115ba 100644 --- a/modules/Kernel/VM/Float.st +++ b/modules/Kernel/VM/Float.st @@ -5,8 +5,127 @@ Extension { #name : #Float } +{ #category : #'instance creation' } +Float class >> fromInteger: anInteger [ + +] + { #category : '*Primitives' } Float class >> new [ ] +{ #category : '*Primitives' } +Float class >> status [ + " Returns the processor's float status register of the last primitive operation " + +] + +{ #category : #arithmetic } +Float >> - aNumber [ + + ^aNumber isFloat + ifTrue: [self errorOn: #'-'] + ifFalse: [self - aNumber asFloat] +] + +{ #category : #arithmetic } +Float >> * aNumber [ + + ^aNumber isFloat + ifTrue: [self errorOn: #'*'] + ifFalse: [self * aNumber asFloat] + +] + +{ #category : #arithmetic } +Float >> / aNumber [ + + ^aNumber isFloat + ifTrue: [self errorOn: #'/'] + ifFalse: [self / aNumber asFloat] +] + +{ #category : #arithmetic } +Float >> + aNumber [ + + ^aNumber isFloat + ifTrue: [ self errorOn: #'+'] + ifFalse: [aNumber addTo: self] +] + +{ #category : #comparing } +Float >> < aNumber [ + + ^aNumber isFloat + ifTrue: [self errorOn: #'<'] + ifFalse: [self < aNumber asFloat] +] + +{ #category : #comparing } +Float >> = aNumber [ + | nan status | + + status := Float status. + ^aNumber isFloat + ifTrue: [ + nan := self isNaN. + (nan and: [aNumber isNaN]) ifTrue: [^true]. + (nan or: [aNumber isNaN]) ifTrue: [^false]. + self errorOn: #'=' status: status] + ifFalse: [aNumber isNumber + ifTrue: [self = aNumber asFloat] + ifFalse: [false]] +] + +{ #category : #testing } +Float >> at: index [ + + ^self primitiveFailed +] + +{ #category : #testing } +Float >> basicAt: index [ + + ^self primitiveFailed +] + +{ #category : #errors } +Float >> errorOn: aSymbol [ + ^self errorOn: aSymbol status: Float status +] + +{ #category : #random } +Float >> fractionPart [ + + self errorOn: #fractionPart +] + +{ #category : #random } +Float >> initializeWith: bytes [ + self replaceBytesFrom: 1 to: 8 with: bytes startingAt: 1 +] + +{ #category : #accessing } +Float >> significand [ + + ^self errorOn: #significand +] + +{ #category : #functions } +Float >> sqrt [ + + ^self errorOn: #sqrt status: status +] + +{ #category : #arithmetic } +Float >> timesTwoPower: anInteger [ + + ^self errorOn: #timesTwoPower status: 0 +] + +{ #category : #arithmetic } +Float >> truncated [ + + ^self errorOn: #truncated status: 0 +] \ No newline at end of file diff --git a/runtime/cpp/Evaluator/Evaluator.cpp b/runtime/cpp/Evaluator/Evaluator.cpp index 60c62d57..5517c1bf 100644 --- a/runtime/cpp/Evaluator/Evaluator.cpp +++ b/runtime/cpp/Evaluator/Evaluator.cpp @@ -148,6 +148,20 @@ void Evaluator::initializePrimitives() this->addPrimitive("PerformWithArguments", &Evaluator::primitivePerformWithArguments); this->addPrimitive("StringReplaceFromToWithStartingAt", &Evaluator::primitiveStringReplaceFromToWithStartingAt); this->addPrimitive("FloatNew", &Evaluator::primitiveFloatNew); + this->addPrimitive("FloatNewFromInteger", &Evaluator::primitiveFloatNewFromInteger); + this->addPrimitive("FloatPlus", &Evaluator::primitiveFloatPlus); + this->addPrimitive("FloatMinus", &Evaluator::primitiveFloatMinus); + this->addPrimitive("FloatMultiply", &Evaluator::primitiveFloatMultiply); + this->addPrimitive("FloatDiv", &Evaluator::primitiveFloatDiv); + this->addPrimitive("FloatLess", &Evaluator::primitiveFloatLess); + this->addPrimitive("FloatEqual", &Evaluator::primitiveFloatEqual); + + this->addPrimitive("FloatFractionPart", &Evaluator::primitiveFloatFractionPart); + this->addPrimitive("FloatSignificand", &Evaluator::primitiveFloatSignificand); + this->addPrimitive("FloatSqrt", &Evaluator::primitiveFloatSqrt); + this->addPrimitive("FloatTimesTwoPower", &Evaluator::primitiveFloatTimesTwoPower); + this->addPrimitive("FloatTruncated", &Evaluator::primitiveFloatTruncated); + this->addPrimitive("FlushDispatchCaches", &Evaluator::primitiveFlushDispatchCaches); //this->addPrimitive("BootstrapDictBeConstant", &Evaluator::primitiveBootstrapDictBeConstant); //this->addPrimitive("BootstrapDictKeys", &Evaluator::primitiveBootstrapDictKeys); @@ -668,6 +682,102 @@ Object* Evaluator::primitiveFloatNew() { return (Object*)this->_runtime->newBytes_size_(this->_context->self()->asHeapObject(), 8); } +Object* Evaluator::primitiveFloatNewFromInteger() { + auto arg = this->_context->firstArgument(); + if (!arg->isSmallInteger()) + return this->failPrimitive(); + + return this->newDoubleObject((double)arg->asSmallInteger()->asNative()); +} + +Object* Evaluator::primitiveFloatPlus() { + auto arg = this->_context->firstArgument(); + if (_runtime->speciesOf_(arg) != _runtime->_floatClass) + return this->failPrimitive(); + + auto self = this->_context->self(); + return this->newDoubleObject(*(double*)self+*(double*)arg); +} + +Object* Evaluator::primitiveFloatMinus() { + auto arg = this->_context->firstArgument(); + if (_runtime->speciesOf_(arg) != _runtime->_floatClass) + return this->failPrimitive(); + + auto self = this->_context->self(); + return this->newDoubleObject(*(double*)self-*(double*)arg); +} + +Object* Evaluator::primitiveFloatMultiply () { + auto arg = this->_context->firstArgument(); + if (_runtime->speciesOf_(arg) != _runtime->_floatClass) + return this->failPrimitive(); + + auto self = this->_context->self(); + return this->newDoubleObject((*(double*)self) * (*(double*)arg)); +} + +Object* Evaluator::primitiveFloatDiv() { + auto arg = this->_context->firstArgument(); + if (_runtime->speciesOf_(arg) != _runtime->_floatClass) + return this->failPrimitive(); + + auto self = this->_context->self(); + return this->newDoubleObject(*(double*)self / *(double*)arg); +} + +Object* Evaluator::primitiveFloatLess() { + auto arg = this->_context->firstArgument(); + if (_runtime->speciesOf_(arg) != _runtime->_floatClass) + return this->failPrimitive(); + + auto self = this->_context->self(); + return this->boolObject(*(double*)self < *(double*)arg); +} + +Object* Evaluator::primitiveFloatEqual() { + auto arg = this->_context->firstArgument(); + if (_runtime->speciesOf_(arg) != _runtime->_floatClass) + return this->failPrimitive(); + + auto self = this->_context->self(); + return this->boolObject(*(double*)self == *(double*)arg); +} + +Object* Evaluator::primitiveFloatFractionPart() { + auto self = this->_context->self(); + double intPart; + return this->newDoubleObject(std::modf(*(double*)self, &intPart)); +} + +Object* Evaluator::primitiveFloatSignificand() { + error_("unimplemented"); + return this->_context->self(); +} + +Object* Evaluator::primitiveFloatSqrt() { + auto self = this->_context->self(); + double intPart; + return this->newDoubleObject(std::sqrt(*(double*)self)); +} + +Object* Evaluator::primitiveFloatTimesTwoPower() { + auto arg = this->_context->firstArgument(); + if (_runtime->speciesOf_(arg) != _runtime->_floatClass) + return this->failPrimitive(); + + auto self = this->_context->self(); + return this->boolObject(*(double*)self == *(double*)arg); +} + +Object* Evaluator::primitiveFloatTruncated() { + auto self = this->_context->self(); + double intPart; + std::modf(*(double*)self, &intPart); + return this->newIntObject(intPart); +} + + Object* Evaluator::primitiveFlushDispatchCaches() { this->_runtime->flushDispatchCache_in_(this->_context->self(), this->_context->firstArgument()->asHeapObject()); return this->_context->self(); diff --git a/runtime/cpp/Evaluator/Evaluator.h b/runtime/cpp/Evaluator/Evaluator.h index 2c62e6fd..ac72fc88 100644 --- a/runtime/cpp/Evaluator/Evaluator.h +++ b/runtime/cpp/Evaluator/Evaluator.h @@ -198,6 +198,20 @@ class Evaluator : public SExpressionVisitor { Object* primitiveClosureValueWithArgs(); Object* primitiveEqual(); Object* primitiveFloatNew(); + Object* primitiveFloatNewFromInteger(); + Object* primitiveFloatPlus(); + Object* primitiveFloatMinus(); + Object* primitiveFloatMultiply(); + Object* primitiveFloatDiv(); + Object* primitiveFloatLess(); + Object* primitiveFloatEqual(); + + Object* primitiveFloatFractionPart(); + Object* primitiveFloatSignificand(); + Object* primitiveFloatSqrt(); + Object* primitiveFloatTimesTwoPower(); + Object* primitiveFloatTruncated(); + Object* primitiveFlushDispatchCaches(); Object* primitiveFlushFromCaches(); diff --git a/runtime/pharo/Powerlang-Core/EggEvaluator.class.st b/runtime/pharo/Powerlang-Core/EggEvaluator.class.st index 345af32c..17c5f4d9 100644 --- a/runtime/pharo/Powerlang-Core/EggEvaluator.class.st +++ b/runtime/pharo/Powerlang-Core/EggEvaluator.class.st @@ -194,6 +194,7 @@ EggEvaluator >> initializePrimitives [ at: #StringReplaceFromToWithStartingAt put: self primitiveStringReplaceFromToWithStartingAt; at: #FloatNew put: self primitiveFloatNew; + at: #FloatNewFromInteger put: self primitiveFloatFromInteger; at: #DictionaryNew put: self primitiveBootstrapDictNew; at: #FlushDispatchCaches put: self primitiveFlushDispatchCaches; at: #BootstrapDictBeConstant @@ -421,6 +422,12 @@ EggEvaluator >> primitiveEqual [ ^ [ runtime booleanFor: context self = context firstArgument ] ] +{ #category : 'primitives' } +EggEvaluator >> primitiveFloatFromInteger [ + ^ [ runtime + newFloat: context firstArgument value asFloat ] +] + { #category : 'primitives' } EggEvaluator >> primitiveFloatNew [ ^ [ runtime newBytesOf: context self sized: 8 ]