mirror of https://github.com/japl-lang/japl.git
738 lines
24 KiB
Nim
738 lines
24 KiB
Nim
# Copyright 2020 Mattia Giambirtone
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# Implementation of numerical types
|
|
|
|
import baseObject
|
|
import typeutils
|
|
|
|
import bitops
|
|
import math
|
|
|
|
# Custom operators for exponentiation
|
|
proc `**`(a, b: int): int = pow(a.float, b.float).int
|
|
proc `**`(a, b: float): float = pow(a, b)
|
|
|
|
|
|
type
|
|
Integer* = object of Obj
|
|
## An integer object
|
|
intValue*: int # TODO: Bignum arithmetic
|
|
Float* = object of Integer
|
|
## A float object
|
|
floatValue*: float
|
|
Infinity* = object of Float # Inf is considered a float
|
|
## An inf object
|
|
isNegative*: bool # This differentiates inf and -inf
|
|
NotANumber* = object of Float # NaN is a subclass of float (as per IEEE 754 spec)
|
|
## A nan object
|
|
|
|
|
|
proc toInt*(obj: ptr Obj): int =
|
|
## Converts a JAPL int to a nim int
|
|
result = cast[ptr Integer](obj).intValue
|
|
|
|
|
|
proc toFloat*(obj: ptr Obj): float =
|
|
## Converts a JAPL float to a nim float
|
|
result = cast[ptr Float](obj).floatValue
|
|
|
|
|
|
proc asInt*(n: int): ptr Integer =
|
|
## Converts a nim int into a JAPL int
|
|
result = allocateObj(Integer, ObjectType.Integer)
|
|
result.intValue = n
|
|
|
|
|
|
|
|
proc asFloat*(n: float): ptr Float =
|
|
## Converts a nim float into a JAPL float
|
|
result = allocateObj(Float, ObjectType.Float)
|
|
result.floatValue = n
|
|
|
|
|
|
|
|
proc asNan*(): ptr NotANumber =
|
|
## Creates a nan object
|
|
result = allocateObj(NotANumber, ObjectType.NotANumber)
|
|
|
|
|
|
proc asInf*(): ptr Infinity =
|
|
## Creates an inf object
|
|
result = allocateObj(Infinity, ObjectType.Infinity)
|
|
|
|
|
|
proc typeName*(self: ptr NotANumber): string =
|
|
result = "nan"
|
|
|
|
|
|
proc typeName*(self: ptr Infinity): string =
|
|
result = "infinity"
|
|
|
|
|
|
proc typeName*(self: ptr Float): string =
|
|
result = "float"
|
|
|
|
|
|
proc stringify*(self: ptr NotANumber): string =
|
|
result = "nan"
|
|
|
|
|
|
proc hash*(self: ptr NotANumber): uint64 =
|
|
# TODO: Hashable?
|
|
raise newException(NotImplementedError, "unhashable type 'nan'")
|
|
|
|
|
|
proc eq*(self, other: ptr NotANumber): bool =
|
|
result = false # As per IEEE 754 spec, nan != nan
|
|
|
|
|
|
proc sum*(self: ptr NotANumber, other: ptr Obj): returnType =
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc stringify*(self: ptr Infinity): string =
|
|
if self.isNegative:
|
|
result = "-inf"
|
|
else:
|
|
result = "inf"
|
|
|
|
|
|
proc isFalsey*(self: ptr Infinity): bool =
|
|
result = false
|
|
|
|
|
|
proc hash*(self: ptr Infinity): uint64 =
|
|
# TODO: Arbitrary hash seems a bad idea
|
|
if self.isNegative:
|
|
result = 1u
|
|
else:
|
|
result = 0u
|
|
|
|
|
|
proc negate*(self: ptr Infinity): returnType =
|
|
result.result = nil
|
|
if self.isNegative:
|
|
result.kind = returnTypes.Inf
|
|
else:
|
|
result.kind = returnTypes.nInf
|
|
|
|
|
|
proc eq*(self, other: ptr Infinity): bool =
|
|
result = self.isNegative == other.isNegative
|
|
|
|
|
|
proc lt*(self: ptr Infinity, other: ptr Obj): tuple[result: bool, obj: ptr Obj] =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
let other = cast[ptr Integer](other)
|
|
if self.isNegative:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
of ObjectType.Float:
|
|
let other = cast[ptr Float](other)
|
|
if self.isNegative:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
of ObjectType.Infinity:
|
|
let other = cast[ptr Infinity](other)
|
|
if other.isNegative and not self.isNegative:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc gt*(self: ptr Infinity, other: ptr Obj): tuple[result: bool, obj: ptr Obj] =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
let other = cast[ptr Integer](other)
|
|
if self.isNegative:
|
|
result = (result: false, obj: nil)
|
|
else:
|
|
result = (result: true, obj: other)
|
|
of ObjectType.Float:
|
|
let other = cast[ptr Float](other)
|
|
if self.isNegative:
|
|
result = (result: false, obj: nil)
|
|
else:
|
|
result = (result: true, obj: other)
|
|
of ObjectType.Infinity:
|
|
let other = cast[ptr Infinity](other)
|
|
if other.isNegative and not self.isNegative:
|
|
result = (result: false, obj: nil)
|
|
else:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc sum*(self: ptr Infinity, other: ptr Obj): returnType =
|
|
result.result = nil
|
|
result.kind = returnTypes.Inf
|
|
case other.kind:
|
|
of ObjectType.Infinity:
|
|
var other = cast[ptr Infinity](other)
|
|
if self.isNegative or other.isNegative:
|
|
result.kind = returnTypes.nInf
|
|
of ObjectType.Integer, ObjectType.Float:
|
|
discard
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc sub*(self: ptr Infinity, other: ptr Obj): returnType =
|
|
result.result = nil
|
|
result.kind = returnTypes.Inf
|
|
case other.kind:
|
|
of ObjectType.Infinity:
|
|
var other = cast[ptr Infinity](other)
|
|
if self.isNegative or other.isNegative:
|
|
result.kind = returnTypes.nInf
|
|
elif not self.isNegative and not other.isNegative:
|
|
result.kind = returnTypes.NotANumber
|
|
of ObjectType.Integer, ObjectType.Float:
|
|
discard
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc stringify*(self: ptr Float): string =
|
|
result = $self.floatValue
|
|
|
|
|
|
proc isFalsey*(self: ptr Float): bool =
|
|
result = false
|
|
|
|
|
|
proc hash*(self: ptr Float): uint64 =
|
|
result = 2166136261u xor uint64 self.floatValue # TODO: Improve this
|
|
result *= 16777619
|
|
|
|
|
|
proc eq*(self, other: ptr Float): bool =
|
|
result = self.floatValue == other.floatValue
|
|
|
|
|
|
proc negate*(self: ptr Float): returnType =
|
|
result.kind = returnTypes.Object
|
|
result.result = (-self.toFloat()).asFloat()
|
|
|
|
|
|
|
|
proc typeName*(self: ptr Integer): string =
|
|
result = "integer"
|
|
|
|
|
|
proc stringify*(self: ptr Integer): string =
|
|
result = $self.intValue
|
|
|
|
|
|
proc isFalsey*(self: ptr Integer): bool =
|
|
result = false
|
|
|
|
|
|
proc eq*(self, other: ptr Integer): bool =
|
|
result = self.intValue == other.intValue
|
|
|
|
|
|
proc negate*(self: ptr Integer): returnType =
|
|
result.kind = returnTypes.Object
|
|
result.result = (-self.toInt()).asInt()
|
|
|
|
|
|
proc hash*(self: ptr Integer): uint64 =
|
|
result = uint64 self.intValue
|
|
|
|
|
|
proc lt*(self: ptr Integer, other: ptr Obj): tuple[result: bool, obj: ptr Obj] =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
if self.intValue < cast[ptr Integer](other).intValue:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
of ObjectType.Float:
|
|
if (float self.intValue) < cast[ptr Float](other).floatValue:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
of ObjectType.Infinity:
|
|
let other = cast[ptr Infinity](other)
|
|
if other.isNegative:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc lt*(self: ptr Float, other: ptr Obj): tuple[result: bool, obj: ptr Obj] =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
if self.floatValue < (float cast[ptr Integer](other).intValue):
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
of ObjectType.Float:
|
|
if self.floatValue < cast[ptr Float](other).floatValue:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
of ObjectType.Infinity:
|
|
let other = cast[ptr Infinity](other)
|
|
if other.isNegative:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc gt*(self: ptr Integer, other: ptr Obj): tuple[result: bool, obj: ptr Obj] =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
if self.intValue > cast[ptr Integer](other).intValue:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
of ObjectType.Float:
|
|
if (float self.intValue) > cast[ptr Float](other).floatValue:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
of ObjectType.Infinity:
|
|
let other = cast[ptr Infinity](other)
|
|
if other.isNegative:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc gt*(self: ptr Float, other: ptr Obj): tuple[result: bool, obj: ptr Obj] =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
if self.floatValue > (float cast[ptr Integer](other).intValue):
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
of ObjectType.Float:
|
|
if self.floatValue > cast[ptr Float](other).floatValue:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
of ObjectType.Infinity:
|
|
let other = cast[ptr Infinity](other)
|
|
if other.isNegative:
|
|
result = (result: true, obj: other)
|
|
else:
|
|
result = (result: false, obj: nil)
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc sum*(self: ptr Integer, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toInt() + cast[ptr Integer](other).toInt()).asInt()
|
|
of ObjectType.Float:
|
|
let res = ((float self.toInt()) + cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc sum*(self: ptr Float, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toFloat() + float cast[ptr Integer](other).toInt()).asFloat()
|
|
of ObjectType.Float:
|
|
let res = (self.toFloat() + cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc sub*(self: ptr Integer, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toInt() - cast[ptr Integer](other).toInt()).asInt()
|
|
of ObjectType.Float:
|
|
let res = ((float self.toInt()) - cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc sub*(self: ptr NotANumber, other: ptr Obj): returnType =
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc sub*(self: ptr Float, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toFloat() - float cast[ptr Integer](other).toInt()).asFloat()
|
|
of ObjectType.Float:
|
|
let res = (self.toFloat() - cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc mul*(self: ptr Infinity, other: ptr Obj): returnType =
|
|
result.result = nil
|
|
result.kind = returnTypes.Inf
|
|
case other.kind:
|
|
of ObjectType.Infinity:
|
|
var other = cast[ptr Infinity](other)
|
|
if self.isNegative or other.isNegative:
|
|
result.kind = returnTypes.nInf
|
|
of ObjectType.Integer, ObjectType.Float:
|
|
discard
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc mul*(self: ptr NotANumber, other: ptr Obj): returnType =
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
|
|
proc mul*(self: ptr Integer, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toInt() * cast[ptr Integer](other).toInt()).asInt()
|
|
of ObjectType.Float:
|
|
let res = ((float self.toInt()) * cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
|
|
proc mul*(self: ptr Float, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toFloat() * float cast[ptr Integer](other).toInt()).asFloat()
|
|
of ObjectType.Float:
|
|
let res = (self.toFloat() * cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc trueDiv*(self: ptr Infinity, other: ptr Obj): returnType =
|
|
result.result = nil
|
|
result.kind = returnTypes.Inf
|
|
case other.kind:
|
|
of ObjectType.Infinity:
|
|
var other = cast[ptr Infinity](other)
|
|
if self.isNegative or other.isNegative:
|
|
result.kind = returnTypes.nInf
|
|
of ObjectType.Integer, ObjectType.Float:
|
|
discard
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc trueDiv*(self: ptr NotANumber, other: ptr Obj): returnType =
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
|
|
proc trueDiv*(self: ptr Integer, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (float(self.toInt()) / float(cast[ptr Integer](other).toInt())).asFloat() # So that 4 / 2 == 2.0
|
|
of ObjectType.Float:
|
|
let res = ((float self.toInt()) / cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc trueDiv*(self: ptr Float, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toFloat() / float cast[ptr Integer](other).toInt()).asFloat()
|
|
of ObjectType.Float:
|
|
let res = (self.toFloat() / cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc pow*(self: ptr Infinity, other: ptr Obj): returnType =
|
|
result.result = nil
|
|
result.kind = returnTypes.Inf
|
|
case other.kind:
|
|
of ObjectType.Infinity:
|
|
var other = cast[ptr Infinity](other)
|
|
if self.isNegative or other.isNegative:
|
|
result.kind = returnTypes.nInf
|
|
of ObjectType.Integer, ObjectType.Float:
|
|
discard
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc pow*(self: ptr NotANumber, other: ptr Obj): returnType =
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
|
|
proc pow*(self: ptr Integer, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toInt() ** cast[ptr Integer](other).toInt()).asInt()
|
|
of ObjectType.Float:
|
|
let res = ((float self.toInt()) ** cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
|
|
proc pow*(self: ptr Float, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toFloat() ** float cast[ptr Integer](other).toInt()).asFloat()
|
|
of ObjectType.Float:
|
|
let res = (self.toFloat() ** cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
|
|
proc divMod*(self: ptr Infinity, other: ptr Obj): returnType =
|
|
result.result = nil
|
|
result.kind = returnTypes.Inf
|
|
case other.kind:
|
|
of ObjectType.Infinity:
|
|
var other = cast[ptr Infinity](other)
|
|
if self.isNegative or other.isNegative:
|
|
result.kind = returnTypes.nInf
|
|
of ObjectType.Integer, ObjectType.Float:
|
|
discard
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc divMod*(self: ptr NotANumber, other: ptr Obj): returnType =
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc divMod*(self: ptr Integer, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toInt() mod cast[ptr Integer](other).toInt()).asInt()
|
|
of ObjectType.Float:
|
|
let res = ((float self.toInt()) mod cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc divMod*(self: ptr Float, other: ptr Obj): returnType =
|
|
case other.kind:
|
|
of ObjectType.Integer:
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toFloat() mod float cast[ptr Integer](other).toInt()).asFloat()
|
|
of ObjectType.Float:
|
|
let res = (self.toFloat() mod cast[ptr Float](other).toFloat())
|
|
if res == system.Inf:
|
|
result.kind = returnTypes.Inf
|
|
result.result = nil
|
|
elif res == -system.Inf:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
result.kind = returnTypes.Object
|
|
result.result = res.asFloat()
|
|
of ObjectType.Infinity:
|
|
result.kind = returnTypes.nInf
|
|
result.result = nil
|
|
else:
|
|
raise newException(NotImplementedError, "")
|
|
|
|
|
|
proc binaryAnd*(self, other: ptr Integer): returnType =
|
|
result.kind = returnTypes.Object
|
|
result.result = bitand(self.toInt(), other.toInt()).asInt()
|
|
|
|
|
|
proc binaryOr*(self, other: ptr Integer): returnType =
|
|
result.kind = returnTypes.Object
|
|
result.result = bitor(self.toInt(), other.toInt()).asInt()
|
|
|
|
|
|
proc binaryNot*(self: ptr Integer): returnType =
|
|
result.kind = returnTypes.Object
|
|
result.result = bitnot(self.toInt()).asInt()
|
|
|
|
|
|
proc binaryXor*(self, other: ptr Integer): returnType =
|
|
result.kind = returnTypes.Object
|
|
result.result = bitxor(self.toInt(), other.toInt()).asInt()
|
|
|
|
|
|
|
|
proc binaryShr*(self, other: ptr Integer): returnType =
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toInt() shr other.toInt()).asInt()
|
|
|
|
|
|
|
|
proc binaryShl*(self, other: ptr Integer): returnType =
|
|
result.kind = returnTypes.Object
|
|
result.result = (self.toInt() shr other.toInt()).asInt()
|