-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* create basic_types, arithmetics, exceptions, comparisons * create setops.nim * create memalloc.nim * create gc_interface.nim * create iterators_1.nim
- Loading branch information
Showing
9 changed files
with
1,700 additions
and
1,649 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
type | ||
int* {.magic: Int.} ## Default integer type; bitwidth depends on | ||
## architecture, but is always the same as a pointer. | ||
int8* {.magic: Int8.} ## Signed 8 bit integer type. | ||
int16* {.magic: Int16.} ## Signed 16 bit integer type. | ||
int32* {.magic: Int32.} ## Signed 32 bit integer type. | ||
int64* {.magic: Int64.} ## Signed 64 bit integer type. | ||
uint* {.magic: UInt.} ## Unsigned default integer type. | ||
uint8* {.magic: UInt8.} ## Unsigned 8 bit integer type. | ||
uint16* {.magic: UInt16.} ## Unsigned 16 bit integer type. | ||
uint32* {.magic: UInt32.} ## Unsigned 32 bit integer type. | ||
uint64* {.magic: UInt64.} ## Unsigned 64 bit integer type. | ||
|
||
type # we need to start a new type section here, so that ``0`` can have a type | ||
bool* {.magic: Bool.} = enum ## Built-in boolean type. | ||
false = 0, true = 1 | ||
|
||
const | ||
on* = true ## Alias for ``true``. | ||
off* = false ## Alias for ``false``. | ||
|
||
type | ||
Ordinal*[T] {.magic: Ordinal.} ## Generic ordinal type. Includes integer, | ||
## bool, character, and enumeration types | ||
## as well as their subtypes. | ||
|
||
SomeSignedInt* = int|int8|int16|int32|int64 | ||
## Type class matching all signed integer types. | ||
|
||
SomeUnsignedInt* = uint|uint8|uint16|uint32|uint64 | ||
## Type class matching all unsigned integer types. | ||
|
||
SomeInteger* = SomeSignedInt|SomeUnsignedInt | ||
## Type class matching all integer types. | ||
|
||
SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint|uint8|uint16|uint32|uint64 | ||
## Type class matching all ordinal types; however this includes enums with | ||
## holes. | ||
|
||
BiggestInt* = int64 | ||
## is an alias for the biggest signed integer type the Nim compiler | ||
## supports. Currently this is ``int64``, but it is platform-dependent | ||
## in general. | ||
|
||
|
||
{.push warning[GcMem]: off, warning[Uninit]: off.} | ||
{.push hints: off.} | ||
|
||
proc `not`*(x: bool): bool {.magic: "Not", noSideEffect.} | ||
## Boolean not; returns true if ``x == false``. | ||
|
||
proc `and`*(x, y: bool): bool {.magic: "And", noSideEffect.} | ||
## Boolean ``and``; returns true if ``x == y == true`` (if both arguments | ||
## are true). | ||
## | ||
## Evaluation is lazy: if ``x`` is false, ``y`` will not even be evaluated. | ||
proc `or`*(x, y: bool): bool {.magic: "Or", noSideEffect.} | ||
## Boolean ``or``; returns true if ``not (not x and not y)`` (if any of | ||
## the arguments is true). | ||
## | ||
## Evaluation is lazy: if ``x`` is true, ``y`` will not even be evaluated. | ||
proc `xor`*(x, y: bool): bool {.magic: "Xor", noSideEffect.} | ||
## Boolean `exclusive or`; returns true if ``x != y`` (if either argument | ||
## is true while the other is false). | ||
|
||
{.pop.} | ||
{.pop.} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,311 @@ | ||
# comparison operators: | ||
proc `==`*[Enum: enum](x, y: Enum): bool {.magic: "EqEnum", noSideEffect.} | ||
## Checks whether values within the *same enum* have the same underlying value. | ||
## | ||
## .. code-block:: Nim | ||
## type | ||
## Enum1 = enum | ||
## Field1 = 3, Field2 | ||
## Enum2 = enum | ||
## Place1, Place2 = 3 | ||
## var | ||
## e1 = Field1 | ||
## e2 = Enum1(Place2) | ||
## echo (e1 == e2) # true | ||
## echo (e1 == Place2) # raises error | ||
proc `==`*(x, y: pointer): bool {.magic: "EqRef", noSideEffect.} | ||
## .. code-block:: Nim | ||
## var # this is a wildly dangerous example | ||
## a = cast[pointer](0) | ||
## b = cast[pointer](nil) | ||
## echo (a == b) # true due to the special meaning of `nil`/0 as a pointer | ||
proc `==`*(x, y: string): bool {.magic: "EqStr", noSideEffect.} | ||
## Checks for equality between two `string` variables. | ||
|
||
proc `==`*(x, y: char): bool {.magic: "EqCh", noSideEffect.} | ||
## Checks for equality between two `char` variables. | ||
proc `==`*(x, y: bool): bool {.magic: "EqB", noSideEffect.} | ||
## Checks for equality between two `bool` variables. | ||
proc `==`*[T](x, y: set[T]): bool {.magic: "EqSet", noSideEffect.} | ||
## Checks for equality between two variables of type `set`. | ||
## | ||
## .. code-block:: Nim | ||
## var a = {1, 2, 2, 3} # duplication in sets is ignored | ||
## var b = {1, 2, 3} | ||
## echo (a == b) # true | ||
proc `==`*[T](x, y: ref T): bool {.magic: "EqRef", noSideEffect.} | ||
## Checks that two `ref` variables refer to the same item. | ||
proc `==`*[T](x, y: ptr T): bool {.magic: "EqRef", noSideEffect.} | ||
## Checks that two `ptr` variables refer to the same item. | ||
proc `==`*[T: proc](x, y: T): bool {.magic: "EqProc", noSideEffect.} | ||
## Checks that two `proc` variables refer to the same procedure. | ||
|
||
proc `<=`*[Enum: enum](x, y: Enum): bool {.magic: "LeEnum", noSideEffect.} | ||
proc `<=`*(x, y: string): bool {.magic: "LeStr", noSideEffect.} | ||
## Compares two strings and returns true if `x` is lexicographically | ||
## before `y` (uppercase letters come before lowercase letters). | ||
## | ||
## .. code-block:: Nim | ||
## let | ||
## a = "abc" | ||
## b = "abd" | ||
## c = "ZZZ" | ||
## assert a <= b | ||
## assert a <= a | ||
## assert (a <= c) == false | ||
proc `<=`*(x, y: char): bool {.magic: "LeCh", noSideEffect.} | ||
## Compares two chars and returns true if `x` is lexicographically | ||
## before `y` (uppercase letters come before lowercase letters). | ||
## | ||
## .. code-block:: Nim | ||
## let | ||
## a = 'a' | ||
## b = 'b' | ||
## c = 'Z' | ||
## assert a <= b | ||
## assert a <= a | ||
## assert (a <= c) == false | ||
proc `<=`*[T](x, y: set[T]): bool {.magic: "LeSet", noSideEffect.} | ||
## Returns true if `x` is a subset of `y`. | ||
## | ||
## A subset `x` has all of its members in `y` and `y` doesn't necessarily | ||
## have more members than `x`. That is, `x` can be equal to `y`. | ||
## | ||
## .. code-block:: Nim | ||
## let | ||
## a = {3, 5} | ||
## b = {1, 3, 5, 7} | ||
## c = {2} | ||
## assert a <= b | ||
## assert a <= a | ||
## assert (a <= c) == false | ||
proc `<=`*(x, y: bool): bool {.magic: "LeB", noSideEffect.} | ||
proc `<=`*[T](x, y: ref T): bool {.magic: "LePtr", noSideEffect.} | ||
proc `<=`*(x, y: pointer): bool {.magic: "LePtr", noSideEffect.} | ||
|
||
proc `<`*[Enum: enum](x, y: Enum): bool {.magic: "LtEnum", noSideEffect.} | ||
proc `<`*(x, y: string): bool {.magic: "LtStr", noSideEffect.} | ||
## Compares two strings and returns true if `x` is lexicographically | ||
## before `y` (uppercase letters come before lowercase letters). | ||
## | ||
## .. code-block:: Nim | ||
## let | ||
## a = "abc" | ||
## b = "abd" | ||
## c = "ZZZ" | ||
## assert a < b | ||
## assert (a < a) == false | ||
## assert (a < c) == false | ||
proc `<`*(x, y: char): bool {.magic: "LtCh", noSideEffect.} | ||
## Compares two chars and returns true if `x` is lexicographically | ||
## before `y` (uppercase letters come before lowercase letters). | ||
## | ||
## .. code-block:: Nim | ||
## let | ||
## a = 'a' | ||
## b = 'b' | ||
## c = 'Z' | ||
## assert a < b | ||
## assert (a < a) == false | ||
## assert (a < c) == false | ||
proc `<`*[T](x, y: set[T]): bool {.magic: "LtSet", noSideEffect.} | ||
## Returns true if `x` is a strict or proper subset of `y`. | ||
## | ||
## A strict or proper subset `x` has all of its members in `y` but `y` has | ||
## more elements than `y`. | ||
## | ||
## .. code-block:: Nim | ||
## let | ||
## a = {3, 5} | ||
## b = {1, 3, 5, 7} | ||
## c = {2} | ||
## assert a < b | ||
## assert (a < a) == false | ||
## assert (a < c) == false | ||
proc `<`*(x, y: bool): bool {.magic: "LtB", noSideEffect.} | ||
proc `<`*[T](x, y: ref T): bool {.magic: "LtPtr", noSideEffect.} | ||
proc `<`*[T](x, y: ptr T): bool {.magic: "LtPtr", noSideEffect.} | ||
proc `<`*(x, y: pointer): bool {.magic: "LtPtr", noSideEffect.} | ||
|
||
template `!=`*(x, y: untyped): untyped = | ||
## Unequals operator. This is a shorthand for ``not (x == y)``. | ||
not (x == y) | ||
|
||
template `>=`*(x, y: untyped): untyped = | ||
## "is greater or equals" operator. This is the same as ``y <= x``. | ||
y <= x | ||
|
||
template `>`*(x, y: untyped): untyped = | ||
## "is greater" operator. This is the same as ``y < x``. | ||
y < x | ||
|
||
|
||
proc `==`*(x, y: int): bool {.magic: "EqI", noSideEffect.} | ||
## Compares two integers for equality. | ||
proc `==`*(x, y: int8): bool {.magic: "EqI", noSideEffect.} | ||
proc `==`*(x, y: int16): bool {.magic: "EqI", noSideEffect.} | ||
proc `==`*(x, y: int32): bool {.magic: "EqI", noSideEffect.} | ||
proc `==`*(x, y: int64): bool {.magic: "EqI", noSideEffect.} | ||
|
||
proc `<=`*(x, y: int): bool {.magic: "LeI", noSideEffect.} | ||
## Returns true if `x` is less than or equal to `y`. | ||
proc `<=`*(x, y: int8): bool {.magic: "LeI", noSideEffect.} | ||
proc `<=`*(x, y: int16): bool {.magic: "LeI", noSideEffect.} | ||
proc `<=`*(x, y: int32): bool {.magic: "LeI", noSideEffect.} | ||
proc `<=`*(x, y: int64): bool {.magic: "LeI", noSideEffect.} | ||
|
||
proc `<`*(x, y: int): bool {.magic: "LtI", noSideEffect.} | ||
## Returns true if `x` is less than `y`. | ||
proc `<`*(x, y: int8): bool {.magic: "LtI", noSideEffect.} | ||
proc `<`*(x, y: int16): bool {.magic: "LtI", noSideEffect.} | ||
proc `<`*(x, y: int32): bool {.magic: "LtI", noSideEffect.} | ||
proc `<`*(x, y: int64): bool {.magic: "LtI", noSideEffect.} | ||
|
||
|
||
proc `<=%`*(x, y: IntMax32): bool {.magic: "LeU", noSideEffect.} | ||
proc `<=%`*(x, y: int64): bool {.magic: "LeU64", noSideEffect.} | ||
## Treats `x` and `y` as unsigned and compares them. | ||
## Returns true if ``unsigned(x) <= unsigned(y)``. | ||
|
||
proc `<%`*(x, y: IntMax32): bool {.magic: "LtU", noSideEffect.} | ||
proc `<%`*(x, y: int64): bool {.magic: "LtU64", noSideEffect.} | ||
## Treats `x` and `y` as unsigned and compares them. | ||
## Returns true if ``unsigned(x) < unsigned(y)``. | ||
|
||
template `>=%`*(x, y: untyped): untyped = y <=% x | ||
## Treats `x` and `y` as unsigned and compares them. | ||
## Returns true if ``unsigned(x) >= unsigned(y)``. | ||
|
||
template `>%`*(x, y: untyped): untyped = y <% x | ||
## Treats `x` and `y` as unsigned and compares them. | ||
## Returns true if ``unsigned(x) > unsigned(y)``. | ||
|
||
|
||
proc `==`*(x, y: uint): bool {.magic: "EqI", noSideEffect.} | ||
## Compares two unsigned integers for equality. | ||
proc `==`*(x, y: uint8): bool {.magic: "EqI", noSideEffect.} | ||
proc `==`*(x, y: uint16): bool {.magic: "EqI", noSideEffect.} | ||
proc `==`*(x, y: uint32): bool {.magic: "EqI", noSideEffect.} | ||
proc `==`*(x, y: uint64): bool {.magic: "EqI", noSideEffect.} | ||
|
||
|
||
proc `<=`*(x, y: uint): bool {.magic: "LeU", noSideEffect.} | ||
## Returns true if ``x <= y``. | ||
proc `<=`*(x, y: uint8): bool {.magic: "LeU", noSideEffect.} | ||
proc `<=`*(x, y: uint16): bool {.magic: "LeU", noSideEffect.} | ||
proc `<=`*(x, y: uint32): bool {.magic: "LeU", noSideEffect.} | ||
proc `<=`*(x, y: uint64): bool {.magic: "LeU", noSideEffect.} | ||
|
||
proc `<`*(x, y: uint): bool {.magic: "LtU", noSideEffect.} | ||
## Returns true if ``unsigned(x) < unsigned(y)``. | ||
proc `<`*(x, y: uint8): bool {.magic: "LtU", noSideEffect.} | ||
proc `<`*(x, y: uint16): bool {.magic: "LtU", noSideEffect.} | ||
proc `<`*(x, y: uint32): bool {.magic: "LtU", noSideEffect.} | ||
proc `<`*(x, y: uint64): bool {.magic: "LtU", noSideEffect.} | ||
|
||
|
||
{.push stackTrace: off.} | ||
|
||
proc min*(x, y: int): int {.magic: "MinI", noSideEffect.} = | ||
if x <= y: x else: y | ||
proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.} = | ||
if x <= y: x else: y | ||
proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.} = | ||
if x <= y: x else: y | ||
proc min*(x, y: int32): int32 {.magic: "MinI", noSideEffect.} = | ||
if x <= y: x else: y | ||
proc min*(x, y: int64): int64 {.magic: "MinI", noSideEffect.} = | ||
## The minimum value of two integers. | ||
if x <= y: x else: y | ||
|
||
proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.} = | ||
if y <= x: x else: y | ||
proc max*(x, y: int8): int8 {.magic: "MaxI", noSideEffect.} = | ||
if y <= x: x else: y | ||
proc max*(x, y: int16): int16 {.magic: "MaxI", noSideEffect.} = | ||
if y <= x: x else: y | ||
proc max*(x, y: int32): int32 {.magic: "MaxI", noSideEffect.} = | ||
if y <= x: x else: y | ||
proc max*(x, y: int64): int64 {.magic: "MaxI", noSideEffect.} = | ||
## The maximum value of two integers. | ||
if y <= x: x else: y | ||
|
||
|
||
proc min*[T](x: openArray[T]): T = | ||
## The minimum value of `x`. ``T`` needs to have a ``<`` operator. | ||
result = x[0] | ||
for i in 1..high(x): | ||
if x[i] < result: result = x[i] | ||
|
||
proc max*[T](x: openArray[T]): T = | ||
## The maximum value of `x`. ``T`` needs to have a ``<`` operator. | ||
result = x[0] | ||
for i in 1..high(x): | ||
if result < x[i]: result = x[i] | ||
|
||
{.pop.} # stackTrace: off | ||
|
||
|
||
proc clamp*[T](x, a, b: T): T = | ||
## Limits the value ``x`` within the interval [a, b]. | ||
## | ||
## .. code-block:: Nim | ||
## assert((1.4).clamp(0.0, 1.0) == 1.0) | ||
## assert((0.5).clamp(0.0, 1.0) == 0.5) | ||
if x < a: return a | ||
if x > b: return b | ||
return x | ||
|
||
|
||
proc `==`*[I, T](x, y: array[I, T]): bool = | ||
for f in low(x)..high(x): | ||
if x[f] != y[f]: | ||
return | ||
result = true | ||
|
||
proc `==`*[T](x, y: openArray[T]): bool = | ||
if x.len != y.len: | ||
return false | ||
for f in low(x)..high(x): | ||
if x[f] != y[f]: | ||
return false | ||
result = true | ||
|
||
|
||
proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} = | ||
## Generic equals operator for sequences: relies on a equals operator for | ||
## the element type `T`. | ||
when nimvm: | ||
when not defined(nimNoNil): | ||
if x.isNil and y.isNil: | ||
return true | ||
else: | ||
if x.len == 0 and y.len == 0: | ||
return true | ||
else: | ||
when not defined(JS): | ||
proc seqToPtr[T](x: seq[T]): pointer {.inline, noSideEffect.} = | ||
when defined(nimSeqsV2): | ||
result = cast[NimSeqV2[T]](x).p | ||
else: | ||
result = cast[pointer](x) | ||
|
||
if seqToPtr(x) == seqToPtr(y): | ||
return true | ||
else: | ||
var sameObject = false | ||
asm """`sameObject` = `x` === `y`""" | ||
if sameObject: return true | ||
|
||
when not defined(nimNoNil): | ||
if x.isNil or y.isNil: | ||
return false | ||
|
||
if x.len != y.len: | ||
return false | ||
|
||
for i in 0..x.len-1: | ||
if x[i] != y[i]: | ||
return false | ||
|
||
return true |
Oops, something went wrong.