moderate system cleanup & refactor (#20355)
* system refactor, move out 600 lines * compilation, slice, backwardsindex, misc_num moved out of system * some procs/types moved into arithmetics, basic_types * system no longer depends on syncio * some procs moved around to fit with their surroundings * make exceptions an import, old ops to misc_num * move instantiationInfo back * move back nim version, fix windows echo * include compilation * better docs for imported modules, fix unsigned ops also remove ze, ze64, toU8, toU16, toU32 with nimPreviewSlimSystem * fix terminal * workaround IC test & weird csize bug, changelog * move NimMajor etc back to compilation, rebase for CI * try ic fix * form single `indices`, slim out TaintedString, try fix IC * fix CI, update changelog, addQuitProc * fix CI * try fix CI * actually fix CI finally hopefully * Update lib/system/compilation.nim Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com> * update kochdocs * hopefully fix csize uses for slimsystem * fix tquit Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
This commit is contained in:
parent
b463c8aedf
commit
919a889ba8
37 changed files with 1167 additions and 1102 deletions
|
|
@ -180,6 +180,8 @@ proc c_printf*(frmt: cstring): cint {.
|
|||
|
||||
proc c_fputs*(c: cstring, f: CFilePtr): cint {.
|
||||
importc: "fputs", header: "<stdio.h>", discardable.}
|
||||
proc c_fputc*(c: char, f: CFilePtr): cint {.
|
||||
importc: "fputc", header: "<stdio.h>", discardable.}
|
||||
|
||||
proc c_sprintf*(buf, frmt: cstring): cint {.
|
||||
importc: "sprintf", header: "<stdio.h>", varargs, noSideEffect.}
|
||||
|
|
@ -212,7 +214,7 @@ else:
|
|||
proc c_fwrite*(buf: pointer, size, n: csize_t, f: CFilePtr): cint {.
|
||||
importc: "fwrite", header: "<stdio.h>".}
|
||||
|
||||
proc c_fflush(f: CFilePtr): cint {.
|
||||
proc c_fflush*(f: CFilePtr): cint {.
|
||||
importc: "fflush", header: "<stdio.h>".}
|
||||
|
||||
proc rawWriteString*(f: CFilePtr, s: cstring, length: int) {.compilerproc, nonReloadable, inline.} =
|
||||
|
|
|
|||
|
|
@ -45,109 +45,6 @@ proc dec*[T: Ordinal](x: var T, y = 1) {.magic: "Dec", noSideEffect.} =
|
|||
# --------------------------------------------------------------------------
|
||||
# built-in operators
|
||||
|
||||
when defined(nimNoZeroExtendMagic):
|
||||
proc ze*(x: int8): int {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int](uint(cast[uint8](x)))
|
||||
|
||||
proc ze*(x: int16): int {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int](uint(cast[uint16](x)))
|
||||
|
||||
proc ze64*(x: int8): int64 {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int64](uint64(cast[uint8](x)))
|
||||
|
||||
proc ze64*(x: int16): int64 {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int64](uint64(cast[uint16](x)))
|
||||
|
||||
proc ze64*(x: int32): int64 {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int64](uint64(cast[uint32](x)))
|
||||
|
||||
proc ze64*(x: int): int64 {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned. Does nothing if the size of an `int` is the same as `int64`.
|
||||
## (This is the case on 64 bit processors.)
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int64](uint64(cast[uint](x)))
|
||||
|
||||
proc toU8*(x: int): int8 {.deprecated.} =
|
||||
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
||||
## from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int8](x)
|
||||
|
||||
proc toU16*(x: int): int16 {.deprecated.} =
|
||||
## treats `x` as unsigned and converts it to an `int16` by taking the last
|
||||
## 16 bits from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int16](x)
|
||||
|
||||
proc toU32*(x: int64): int32 {.deprecated.} =
|
||||
## treats `x` as unsigned and converts it to an `int32` by taking the
|
||||
## last 32 bits from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int32](x)
|
||||
|
||||
elif not defined(js):
|
||||
proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc ze64*(x: int): int64 {.magic: "ZeIToI64", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned. Does nothing if the size of an `int` is the same as `int64`.
|
||||
## (This is the case on 64 bit processors.)
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect, deprecated.}
|
||||
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
||||
## from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect, deprecated.}
|
||||
## treats `x` as unsigned and converts it to an `int16` by taking the last
|
||||
## 16 bits from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect, deprecated.}
|
||||
## treats `x` as unsigned and converts it to an `int32` by taking the
|
||||
## last 32 bits from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
# integer calculations:
|
||||
proc `+`*(x: int): int {.magic: "UnaryPlusI", noSideEffect.}
|
||||
## Unary `+` operator for an integer. Has no effect.
|
||||
|
|
@ -399,6 +296,59 @@ proc `mod`*(x, y: uint16): uint16 {.magic: "ModU", noSideEffect.}
|
|||
proc `mod`*(x, y: uint32): uint32 {.magic: "ModU", noSideEffect.}
|
||||
proc `mod`*(x, y: uint64): uint64 {.magic: "ModU", noSideEffect.}
|
||||
|
||||
proc `+=`*[T: SomeInteger](x: var T, y: T) {.
|
||||
magic: "Inc", noSideEffect.}
|
||||
## Increments an integer.
|
||||
|
||||
proc `-=`*[T: SomeInteger](x: var T, y: T) {.
|
||||
magic: "Dec", noSideEffect.}
|
||||
## Decrements an integer.
|
||||
|
||||
proc `*=`*[T: SomeInteger](x: var T, y: T) {.
|
||||
inline, noSideEffect.} =
|
||||
## Binary `*=` operator for integers.
|
||||
x = x * y
|
||||
|
||||
# floating point operations:
|
||||
proc `+`*(x: float32): float32 {.magic: "UnaryPlusF64", noSideEffect.}
|
||||
proc `-`*(x: float32): float32 {.magic: "UnaryMinusF64", noSideEffect.}
|
||||
proc `+`*(x, y: float32): float32 {.magic: "AddF64", noSideEffect.}
|
||||
proc `-`*(x, y: float32): float32 {.magic: "SubF64", noSideEffect.}
|
||||
proc `*`*(x, y: float32): float32 {.magic: "MulF64", noSideEffect.}
|
||||
proc `/`*(x, y: float32): float32 {.magic: "DivF64", noSideEffect.}
|
||||
|
||||
proc `+`*(x: float): float {.magic: "UnaryPlusF64", noSideEffect.}
|
||||
proc `-`*(x: float): float {.magic: "UnaryMinusF64", noSideEffect.}
|
||||
proc `+`*(x, y: float): float {.magic: "AddF64", noSideEffect.}
|
||||
proc `-`*(x, y: float): float {.magic: "SubF64", noSideEffect.}
|
||||
proc `*`*(x, y: float): float {.magic: "MulF64", noSideEffect.}
|
||||
proc `/`*(x, y: float): float {.magic: "DivF64", noSideEffect.}
|
||||
|
||||
proc `+=`*[T: float|float32|float64] (x: var T, y: T) {.
|
||||
inline, noSideEffect.} =
|
||||
## Increments in place a floating point number.
|
||||
x = x + y
|
||||
|
||||
proc `-=`*[T: float|float32|float64] (x: var T, y: T) {.
|
||||
inline, noSideEffect.} =
|
||||
## Decrements in place a floating point number.
|
||||
x = x - y
|
||||
|
||||
proc `*=`*[T: float|float32|float64] (x: var T, y: T) {.
|
||||
inline, noSideEffect.} =
|
||||
## Multiplies in place a floating point number.
|
||||
x = x * y
|
||||
|
||||
proc `/=`*(x: var float64, y: float64) {.inline, noSideEffect.} =
|
||||
## Divides in place a floating point number.
|
||||
x = x / y
|
||||
|
||||
proc `/=`*[T: float|float32](x: var T, y: T) {.inline, noSideEffect.} =
|
||||
## Divides in place a floating point number.
|
||||
x = x / y
|
||||
|
||||
# the following have to be included in system, not imported for some reason:
|
||||
|
||||
proc `+%`*(x, y: int): int {.inline.} =
|
||||
## Treats `x` and `y` as unsigned and adds them.
|
||||
##
|
||||
|
|
@ -454,15 +404,106 @@ proc `%%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) mod cast
|
|||
proc `%%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) mod cast[uint32](y))
|
||||
proc `%%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) mod cast[uint64](y))
|
||||
|
||||
proc `+=`*[T: SomeInteger](x: var T, y: T) {.
|
||||
magic: "Inc", noSideEffect.}
|
||||
## Increments an integer.
|
||||
when not defined(nimPreviewSlimSystem):
|
||||
when defined(nimNoZeroExtendMagic):
|
||||
proc ze*(x: int8): int {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int](uint(cast[uint8](x)))
|
||||
|
||||
proc `-=`*[T: SomeInteger](x: var T, y: T) {.
|
||||
magic: "Dec", noSideEffect.}
|
||||
## Decrements an integer.
|
||||
proc ze*(x: int16): int {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int](uint(cast[uint16](x)))
|
||||
|
||||
proc `*=`*[T: SomeInteger](x: var T, y: T) {.
|
||||
inline, noSideEffect.} =
|
||||
## Binary `*=` operator for integers.
|
||||
x = x * y
|
||||
proc ze64*(x: int8): int64 {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int64](uint64(cast[uint8](x)))
|
||||
|
||||
proc ze64*(x: int16): int64 {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int64](uint64(cast[uint16](x)))
|
||||
|
||||
proc ze64*(x: int32): int64 {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int64](uint64(cast[uint32](x)))
|
||||
|
||||
proc ze64*(x: int): int64 {.deprecated.} =
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned. Does nothing if the size of an `int` is the same as `int64`.
|
||||
## (This is the case on 64 bit processors.)
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int64](uint64(cast[uint](x)))
|
||||
|
||||
proc toU8*(x: int): int8 {.deprecated.} =
|
||||
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
||||
## from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int8](x)
|
||||
|
||||
proc toU16*(x: int): int16 {.deprecated.} =
|
||||
## treats `x` as unsigned and converts it to an `int16` by taking the last
|
||||
## 16 bits from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int16](x)
|
||||
|
||||
proc toU32*(x: int64): int32 {.deprecated.} =
|
||||
## treats `x` as unsigned and converts it to an `int32` by taking the
|
||||
## last 32 bits from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
cast[int32](x)
|
||||
|
||||
elif not defined(js):
|
||||
proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc ze64*(x: int): int64 {.magic: "ZeIToI64", noSideEffect, deprecated.}
|
||||
## zero extends a smaller integer type to `int64`. This treats `x` as
|
||||
## unsigned. Does nothing if the size of an `int` is the same as `int64`.
|
||||
## (This is the case on 64 bit processors.)
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect, deprecated.}
|
||||
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
||||
## from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect, deprecated.}
|
||||
## treats `x` as unsigned and converts it to an `int16` by taking the last
|
||||
## 16 bits from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
||||
proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect, deprecated.}
|
||||
## treats `x` as unsigned and converts it to an `int32` by taking the
|
||||
## last 32 bits from `x`.
|
||||
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||
|
|
|
|||
|
|
@ -1,15 +1,45 @@
|
|||
type
|
||||
int* {.magic: "Int".} ## Default integer type; bitwidth depends on
|
||||
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.
|
||||
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
|
||||
float* {.magic: Float.} ## Default floating point type.
|
||||
float32* {.magic: Float32.} ## 32 bit floating point type.
|
||||
float64* {.magic: Float.} ## 64 bit floating point type.
|
||||
|
||||
# 'float64' is now an alias to 'float'; this solves many problems
|
||||
|
||||
type
|
||||
char* {.magic: Char.} ## Built-in 8 bit character type (unsigned).
|
||||
string* {.magic: String.} ## Built-in string type.
|
||||
cstring* {.magic: Cstring.} ## Built-in cstring (*compatible string*) type.
|
||||
pointer* {.magic: Pointer.} ## Built-in pointer type, use the `addr`
|
||||
## operator to get a pointer to a variable.
|
||||
|
||||
typedesc* {.magic: TypeDesc.} ## Meta type to denote a type description.
|
||||
|
||||
type
|
||||
`ptr`*[T] {.magic: Pointer.} ## Built-in generic untraced pointer type.
|
||||
`ref`*[T] {.magic: Pointer.} ## Built-in generic traced pointer type.
|
||||
|
||||
`nil` {.magic: "Nil".}
|
||||
|
||||
void* {.magic: "VoidType".} ## Meta type to denote the absence of any type.
|
||||
auto* {.magic: Expr.} ## Meta type for automatic type determination.
|
||||
any* {.deprecated: "Deprecated since v1.5; Use auto instead.".} = distinct auto ## Deprecated; Use `auto` instead. See https://github.com/nim-lang/RFCs/issues/281
|
||||
untyped* {.magic: Expr.} ## Meta type to denote an expression that
|
||||
## is not resolved (for templates).
|
||||
typed* {.magic: Stmt.} ## Meta type to denote an expression that
|
||||
## is resolved (for templates).
|
||||
|
||||
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.
|
||||
|
|
@ -29,15 +59,16 @@ type
|
|||
SomeInteger* = SomeSignedInt|SomeUnsignedInt
|
||||
## Type class matching all integer types.
|
||||
|
||||
SomeFloat* = float|float32|float64
|
||||
## Type class matching all floating point number types.
|
||||
|
||||
SomeNumber* = SomeInteger|SomeFloat
|
||||
## Type class matching all number 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. See also `Ordinal`
|
||||
|
||||
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.}
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@ proc raiseFieldError(f: string) {.compilerproc, noinline.} =
|
|||
when defined(nimV2):
|
||||
proc raiseFieldError2(f: string, discVal: int) {.compilerproc, noinline.} =
|
||||
## raised when field is inaccessible given runtime value of discriminant
|
||||
sysFatal(FieldError, f & $discVal & "'")
|
||||
sysFatal(FieldDefect, f & $discVal & "'")
|
||||
else:
|
||||
proc raiseFieldError2(f: string, discVal: string) {.compilerproc, noinline.} =
|
||||
## raised when field is inaccessible given runtime value of discriminant
|
||||
sysFatal(FieldError, formatFieldDefect(f, discVal))
|
||||
sysFatal(FieldDefect, formatFieldDefect(f, discVal))
|
||||
|
||||
proc raiseRangeErrorI(i, a, b: BiggestInt) {.compilerproc, noinline.} =
|
||||
when defined(standalone):
|
||||
|
|
|
|||
|
|
@ -206,6 +206,14 @@ 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: float32): bool {.magic: "LeF64", noSideEffect.}
|
||||
proc `<=`*(x, y: float): bool {.magic: "LeF64", noSideEffect.}
|
||||
|
||||
proc `<`*(x, y: float32): bool {.magic: "LtF64", noSideEffect.}
|
||||
proc `<`*(x, y: float): bool {.magic: "LtF64", noSideEffect.}
|
||||
|
||||
proc `==`*(x, y: float32): bool {.magic: "EqF64", noSideEffect.}
|
||||
proc `==`*(x, y: float): bool {.magic: "EqF64", noSideEffect.}
|
||||
|
||||
{.push stackTrace: off.}
|
||||
|
||||
|
|
@ -220,6 +228,13 @@ proc min*(x, y: int32): int32 {.magic: "MinI", noSideEffect.} =
|
|||
proc min*(x, y: int64): int64 {.magic: "MinI", noSideEffect.} =
|
||||
## The minimum value of two integers.
|
||||
if x <= y: x else: y
|
||||
proc min*(x, y: float32): float32 {.noSideEffect, inline.} =
|
||||
if x <= y or y != y: x else: y
|
||||
proc min*(x, y: float64): float64 {.noSideEffect, inline.} =
|
||||
if x <= y or y != y: x else: y
|
||||
proc min*[T: not SomeFloat](x, y: T): T {.inline.} =
|
||||
## Generic minimum operator of 2 values based on `<=`.
|
||||
if x <= y: x else: y
|
||||
|
||||
proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.} =
|
||||
if y <= x: x else: y
|
||||
|
|
@ -232,6 +247,13 @@ proc max*(x, y: int32): int32 {.magic: "MaxI", noSideEffect.} =
|
|||
proc max*(x, y: int64): int64 {.magic: "MaxI", noSideEffect.} =
|
||||
## The maximum value of two integers.
|
||||
if y <= x: x else: y
|
||||
proc max*(x, y: float32): float32 {.noSideEffect, inline.} =
|
||||
if y <= x or y != y: x else: y
|
||||
proc max*(x, y: float64): float64 {.noSideEffect, inline.} =
|
||||
if y <= x or y != y: x else: y
|
||||
proc max*[T: not SomeFloat](x, y: T): T {.inline.} =
|
||||
## Generic maximum operator of 2 values based on `<=`.
|
||||
if y <= x: x else: y
|
||||
|
||||
|
||||
proc min*[T](x: openArray[T]): T =
|
||||
|
|
|
|||
214
lib/system/compilation.nim
Normal file
214
lib/system/compilation.nim
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
const
|
||||
NimMajor* {.intdefine.}: int = 1
|
||||
## is the major number of Nim's version. Example:
|
||||
## ```
|
||||
## when (NimMajor, NimMinor, NimPatch) >= (1, 3, 1): discard
|
||||
## ```
|
||||
# see also std/private/since
|
||||
|
||||
NimMinor* {.intdefine.}: int = 7
|
||||
## is the minor number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
NimPatch* {.intdefine.}: int = 3
|
||||
## is the patch number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
{.push profiler: off.}
|
||||
let nimvm* {.magic: "Nimvm", compileTime.}: bool = false
|
||||
## May be used only in `when` expression.
|
||||
## It is true in Nim VM context and false otherwise.
|
||||
{.pop.}
|
||||
|
||||
const
|
||||
isMainModule* {.magic: "IsMainModule".}: bool = false
|
||||
## True only when accessed in the main module. This works thanks to
|
||||
## compiler magic. It is useful to embed testing code in a module.
|
||||
|
||||
CompileDate* {.magic: "CompileDate".}: string = "0000-00-00"
|
||||
## The date (in UTC) of compilation as a string of the form
|
||||
## `YYYY-MM-DD`. This works thanks to compiler magic.
|
||||
|
||||
CompileTime* {.magic: "CompileTime".}: string = "00:00:00"
|
||||
## The time (in UTC) of compilation as a string of the form
|
||||
## `HH:MM:SS`. This works thanks to compiler magic.
|
||||
|
||||
proc defined*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
|
||||
## Special compile-time procedure that checks whether `x` is
|
||||
## defined.
|
||||
##
|
||||
## `x` is an external symbol introduced through the compiler's
|
||||
## `-d:x switch <nimc.html#compiler-usage-compileminustime-symbols>`_ to enable
|
||||
## build time conditionals:
|
||||
## ```
|
||||
## when not defined(release):
|
||||
## # Do here programmer friendly expensive sanity checks.
|
||||
## # Put here the normal code
|
||||
## ```
|
||||
##
|
||||
## See also:
|
||||
## * `compileOption <#compileOption,string>`_ for `on|off` options
|
||||
## * `compileOption <#compileOption,string,string>`_ for enum options
|
||||
## * `define pragmas <manual.html#implementation-specific-pragmas-compileminustime-define-pragmas>`_
|
||||
|
||||
when defined(nimHasDeclaredMagic):
|
||||
proc declared*(x: untyped): bool {.magic: "Declared", noSideEffect, compileTime.}
|
||||
## Special compile-time procedure that checks whether `x` is
|
||||
## declared. `x` has to be an identifier or a qualified identifier.
|
||||
##
|
||||
## This can be used to check whether a library provides a certain
|
||||
## feature or not:
|
||||
## ```
|
||||
## when not declared(strutils.toUpper):
|
||||
## # provide our own toUpper proc here, because strutils is
|
||||
## # missing it.
|
||||
## ```
|
||||
##
|
||||
## See also:
|
||||
## * `declaredInScope <#declaredInScope,untyped>`_
|
||||
else:
|
||||
proc declared*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
|
||||
|
||||
when defined(nimHasDeclaredMagic):
|
||||
proc declaredInScope*(x: untyped): bool {.magic: "DeclaredInScope", noSideEffect, compileTime.}
|
||||
## Special compile-time procedure that checks whether `x` is
|
||||
## declared in the current scope. `x` has to be an identifier.
|
||||
else:
|
||||
proc declaredInScope*(x: untyped): bool {.magic: "DefinedInScope", noSideEffect, compileTime.}
|
||||
|
||||
proc compiles*(x: untyped): bool {.magic: "Compiles", noSideEffect, compileTime.} =
|
||||
## Special compile-time procedure that checks whether `x` can be compiled
|
||||
## without any semantic error.
|
||||
## This can be used to check whether a type supports some operation:
|
||||
## ```
|
||||
## when compiles(3 + 4):
|
||||
## echo "'+' for integers is available"
|
||||
## ```
|
||||
discard
|
||||
|
||||
proc astToStr*[T](x: T): string {.magic: "AstToStr", noSideEffect.}
|
||||
## Converts the AST of `x` into a string representation. This is very useful
|
||||
## for debugging.
|
||||
|
||||
proc runnableExamples*(rdoccmd = "", body: untyped) {.magic: "RunnableExamples".} =
|
||||
## A section you should use to mark `runnable example`:idx: code with.
|
||||
##
|
||||
## - In normal debug and release builds code within
|
||||
## a `runnableExamples` section is ignored.
|
||||
## - The documentation generator is aware of these examples and considers them
|
||||
## part of the `##` doc comment. As the last step of documentation
|
||||
## generation each runnableExample is put in its own file `$file_examples$i.nim`,
|
||||
## compiled and tested. The collected examples are
|
||||
## put into their own module to ensure the examples do not refer to
|
||||
## non-exported symbols.
|
||||
runnableExamples:
|
||||
proc timesTwo*(x: int): int =
|
||||
## This proc doubles a number.
|
||||
runnableExamples:
|
||||
# at module scope
|
||||
const exported* = 123
|
||||
assert timesTwo(5) == 10
|
||||
block: # at block scope
|
||||
defer: echo "done"
|
||||
runnableExamples "-d:foo -b:cpp":
|
||||
import std/compilesettings
|
||||
assert querySetting(backend) == "cpp"
|
||||
assert defined(foo)
|
||||
runnableExamples "-r:off": ## this one is only compiled
|
||||
import std/browsers
|
||||
openDefaultBrowser "https://forum.nim-lang.org/"
|
||||
2 * x
|
||||
|
||||
proc compileOption*(option: string): bool {.
|
||||
magic: "CompileOption", noSideEffect.} =
|
||||
## Can be used to determine an `on|off` compile-time option.
|
||||
##
|
||||
## See also:
|
||||
## * `compileOption <#compileOption,string,string>`_ for enum options
|
||||
## * `defined <#defined,untyped>`_
|
||||
## * `std/compilesettings module <compilesettings.html>`_
|
||||
runnableExamples("--floatChecks:off"):
|
||||
static: doAssert not compileOption("floatchecks")
|
||||
{.push floatChecks: on.}
|
||||
static: doAssert compileOption("floatchecks")
|
||||
# floating point NaN and Inf checks enabled in this scope
|
||||
{.pop.}
|
||||
|
||||
proc compileOption*(option, arg: string): bool {.
|
||||
magic: "CompileOptionArg", noSideEffect.} =
|
||||
## Can be used to determine an enum compile-time option.
|
||||
##
|
||||
## See also:
|
||||
## * `compileOption <#compileOption,string>`_ for `on|off` options
|
||||
## * `defined <#defined,untyped>`_
|
||||
## * `std/compilesettings module <compilesettings.html>`_
|
||||
runnableExamples:
|
||||
when compileOption("opt", "size") and compileOption("gc", "boehm"):
|
||||
discard "compiled with optimization for size and uses Boehm's GC"
|
||||
|
||||
template currentSourcePath*: string = instantiationInfo(-1, true).filename
|
||||
## Returns the full file-system path of the current source.
|
||||
##
|
||||
## To get the directory containing the current source, use it with
|
||||
## `os.parentDir() <os.html#parentDir%2Cstring>`_ as `currentSourcePath.parentDir()`.
|
||||
##
|
||||
## The path returned by this template is set at compile time.
|
||||
##
|
||||
## See the docstring of `macros.getProjectPath() <macros.html#getProjectPath>`_
|
||||
## for an example to see the distinction between the `currentSourcePath`
|
||||
## and `getProjectPath`.
|
||||
##
|
||||
## See also:
|
||||
## * `getCurrentDir proc <os.html#getCurrentDir>`_
|
||||
|
||||
proc slurp*(filename: string): string {.magic: "Slurp".}
|
||||
## This is an alias for `staticRead <#staticRead,string>`_.
|
||||
|
||||
proc staticRead*(filename: string): string {.magic: "Slurp".}
|
||||
## Compile-time `readFile <syncio.html#readFile,string>`_ proc for easy
|
||||
## `resource`:idx: embedding:
|
||||
##
|
||||
## The maximum file size limit that `staticRead` and `slurp` can read is
|
||||
## near or equal to the *free* memory of the device you are using to compile.
|
||||
## ```
|
||||
## const myResource = staticRead"mydatafile.bin"
|
||||
## ```
|
||||
##
|
||||
## `slurp <#slurp,string>`_ is an alias for `staticRead`.
|
||||
|
||||
proc gorge*(command: string, input = "", cache = ""): string {.
|
||||
magic: "StaticExec".} = discard
|
||||
## This is an alias for `staticExec <#staticExec,string,string,string>`_.
|
||||
|
||||
proc staticExec*(command: string, input = "", cache = ""): string {.
|
||||
magic: "StaticExec".} = discard
|
||||
## Executes an external process at compile-time and returns its text output
|
||||
## (stdout + stderr).
|
||||
##
|
||||
## If `input` is not an empty string, it will be passed as a standard input
|
||||
## to the executed program.
|
||||
## ```
|
||||
## const buildInfo = "Revision " & staticExec("git rev-parse HEAD") &
|
||||
## "\nCompiled on " & staticExec("uname -v")
|
||||
## ```
|
||||
##
|
||||
## `gorge <#gorge,string,string,string>`_ is an alias for `staticExec`.
|
||||
##
|
||||
## Note that you can use this proc inside a pragma like
|
||||
## `passc <manual.html#implementation-specific-pragmas-passc-pragma>`_ or
|
||||
## `passl <manual.html#implementation-specific-pragmas-passl-pragma>`_.
|
||||
##
|
||||
## If `cache` is not empty, the results of `staticExec` are cached within
|
||||
## the `nimcache` directory. Use `--forceBuild` to get rid of this caching
|
||||
## behaviour then. `command & input & cache` (the concatenated string) is
|
||||
## used to determine whether the entry in the cache is still valid. You can
|
||||
## use versioning information for `cache`:
|
||||
## ```
|
||||
## const stateMachine = staticExec("dfaoptimizer", "input", "0.8.0")
|
||||
## ```
|
||||
|
||||
proc gorgeEx*(command: string, input = "", cache = ""): tuple[output: string,
|
||||
exitCode: int] =
|
||||
## Similar to `gorge <#gorge,string,string,string>`_ but also returns the
|
||||
## precious exit code.
|
||||
discard
|
||||
90
lib/system/ctypes.nim
Normal file
90
lib/system/ctypes.nim
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
## Some type definitions for compatibility between different
|
||||
## backends and platforms.
|
||||
|
||||
type
|
||||
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.
|
||||
|
||||
BiggestFloat* = float64
|
||||
## is an alias for the biggest floating point type the Nim
|
||||
## compiler supports. Currently this is `float64`, but it is
|
||||
## platform-dependent in general.
|
||||
|
||||
when defined(js):
|
||||
type BiggestUInt* = uint32
|
||||
## is an alias for the biggest unsigned integer type the Nim compiler
|
||||
## supports. Currently this is `uint32` for JS and `uint64` for other
|
||||
## targets.
|
||||
else:
|
||||
type BiggestUInt* = uint64
|
||||
## is an alias for the biggest unsigned integer type the Nim compiler
|
||||
## supports. Currently this is `uint32` for JS and `uint64` for other
|
||||
## targets.
|
||||
|
||||
when defined(windows):
|
||||
type
|
||||
clong* {.importc: "long", nodecl.} = int32
|
||||
## This is the same as the type `long` in *C*.
|
||||
culong* {.importc: "unsigned long", nodecl.} = uint32
|
||||
## This is the same as the type `unsigned long` in *C*.
|
||||
else:
|
||||
type
|
||||
clong* {.importc: "long", nodecl.} = int
|
||||
## This is the same as the type `long` in *C*.
|
||||
culong* {.importc: "unsigned long", nodecl.} = uint
|
||||
## This is the same as the type `unsigned long` in *C*.
|
||||
|
||||
type # these work for most platforms:
|
||||
cchar* {.importc: "char", nodecl.} = char
|
||||
## This is the same as the type `char` in *C*.
|
||||
cschar* {.importc: "signed char", nodecl.} = int8
|
||||
## This is the same as the type `signed char` in *C*.
|
||||
cshort* {.importc: "short", nodecl.} = int16
|
||||
## This is the same as the type `short` in *C*.
|
||||
cint* {.importc: "int", nodecl.} = int32
|
||||
## This is the same as the type `int` in *C*.
|
||||
csize_t* {.importc: "size_t", nodecl.} = uint
|
||||
## This is the same as the type `size_t` in *C*.
|
||||
clonglong* {.importc: "long long", nodecl.} = int64
|
||||
## This is the same as the type `long long` in *C*.
|
||||
cfloat* {.importc: "float", nodecl.} = float32
|
||||
## This is the same as the type `float` in *C*.
|
||||
cdouble* {.importc: "double", nodecl.} = float64
|
||||
## This is the same as the type `double` in *C*.
|
||||
clongdouble* {.importc: "long double", nodecl.} = BiggestFloat
|
||||
## This is the same as the type `long double` in *C*.
|
||||
## This C type is not supported by Nim's code generator.
|
||||
|
||||
cuchar* {.importc: "unsigned char", nodecl, deprecated: "use `char` or `uint8` instead".} = char
|
||||
## Deprecated: Use `uint8` instead.
|
||||
cushort* {.importc: "unsigned short", nodecl.} = uint16
|
||||
## This is the same as the type `unsigned short` in *C*.
|
||||
cuint* {.importc: "unsigned int", nodecl.} = uint32
|
||||
## This is the same as the type `unsigned int` in *C*.
|
||||
culonglong* {.importc: "unsigned long long", nodecl.} = uint64
|
||||
## This is the same as the type `unsigned long long` in *C*.
|
||||
|
||||
type
|
||||
ByteAddress* = int
|
||||
## is the signed integer type that should be used for converting
|
||||
## pointers to integer addresses for readability.
|
||||
|
||||
cstringArray* {.importc: "char**", nodecl.} = ptr UncheckedArray[cstring]
|
||||
## This is binary compatible to the type `char**` in *C*. The array's
|
||||
## high value is large enough to disable bounds checking in practice.
|
||||
## Use `cstringArrayToSeq proc <#cstringArrayToSeq,cstringArray,Natural>`_
|
||||
## to convert it into a `seq[string]`.
|
||||
|
||||
when not defined(nimPreviewSlimSystem):
|
||||
# pollutes namespace
|
||||
type
|
||||
PFloat32* {.deprecated: "use `ptr float32`".} = ptr float32
|
||||
## An alias for `ptr float32`.
|
||||
PFloat64* {.deprecated: "use `ptr float64`".} = ptr float64
|
||||
## An alias for `ptr float64`.
|
||||
PInt64* {.deprecated: "use `ptr int64`".} = ptr int64
|
||||
## An alias for `ptr int64`.
|
||||
PInt32* {.deprecated: "use `ptr int32`".} = ptr int32
|
||||
## An alias for `ptr int32`.
|
||||
|
|
@ -1,61 +1,13 @@
|
|||
const NimStackTraceMsgs =
|
||||
when defined(nimHasStacktraceMsgs): compileOption("stacktraceMsgs")
|
||||
else: false
|
||||
## Exception and effect types used in Nim code.
|
||||
|
||||
type
|
||||
RootEffect* {.compilerproc.} = object of RootObj ## \
|
||||
## Base effect class.
|
||||
##
|
||||
## Each effect should inherit from `RootEffect` unless you know what
|
||||
## you're doing.
|
||||
TimeEffect* = object of RootEffect ## Time effect.
|
||||
IOEffect* = object of RootEffect ## IO effect.
|
||||
ReadIOEffect* = object of IOEffect ## Effect describing a read IO operation.
|
||||
WriteIOEffect* = object of IOEffect ## Effect describing a write IO operation.
|
||||
ExecIOEffect* = object of IOEffect ## Effect describing an executing IO operation.
|
||||
|
||||
StackTraceEntry* = object ## In debug mode exceptions store the stack trace that led
|
||||
## to them. A `StackTraceEntry` is a single entry of the
|
||||
## stack trace.
|
||||
procname*: cstring ## Name of the proc that is currently executing.
|
||||
line*: int ## Line number of the proc that is currently executing.
|
||||
filename*: cstring ## Filename of the proc that is currently executing.
|
||||
when NimStackTraceMsgs:
|
||||
frameMsg*: string ## When a stacktrace is generated in a given frame and
|
||||
## rendered at a later time, we should ensure the stacktrace
|
||||
## data isn't invalidated; any pointer into PFrame is
|
||||
## subject to being invalidated so shouldn't be stored.
|
||||
when defined(nimStackTraceOverride):
|
||||
programCounter*: uint ## Program counter - will be used to get the rest of the info,
|
||||
## when `$` is called on this type. We can't use
|
||||
## "cuintptr_t" in here.
|
||||
procnameStr*, filenameStr*: string ## GC-ed alternatives to "procname" and "filename"
|
||||
|
||||
Exception* {.compilerproc, magic: "Exception".} = object of RootObj ## \
|
||||
## Base exception class.
|
||||
##
|
||||
## Each exception has to inherit from `Exception`. See the full `exception
|
||||
## hierarchy <manual.html#exception-handling-exception-hierarchy>`_.
|
||||
parent*: ref Exception ## Parent exception (can be used as a stack).
|
||||
name*: cstring ## The exception's name is its Nim identifier.
|
||||
## This field is filled automatically in the
|
||||
## `raise` statement.
|
||||
msg* {.exportc: "message".}: string ## The exception's message. Not
|
||||
## providing an exception message
|
||||
## is bad style.
|
||||
when defined(js):
|
||||
trace: string
|
||||
else:
|
||||
trace: seq[StackTraceEntry]
|
||||
up: ref Exception # used for stacking exceptions. Not exported!
|
||||
|
||||
Defect* = object of Exception ## \
|
||||
## Abstract base class for all exceptions that Nim's runtime raises
|
||||
## but that are strictly uncatchable as they can also be mapped to
|
||||
## a `quit` / `trap` / `exit` operation.
|
||||
|
||||
CatchableError* = object of Exception ## \
|
||||
## Abstract class for all exceptions that are catchable.
|
||||
type
|
||||
IOError* = object of CatchableError ## \
|
||||
## Raised if an IO error occurred.
|
||||
EOFError* = object of IOError ## \
|
||||
|
|
@ -144,25 +96,27 @@ type
|
|||
##
|
||||
## This is only raised if the `segfaults module <segfaults.html>`_ was imported!
|
||||
|
||||
ArithmeticError* {.deprecated: "See corresponding Defect".} = ArithmeticDefect
|
||||
DivByZeroError* {.deprecated: "See corresponding Defect".} = DivByZeroDefect
|
||||
OverflowError* {.deprecated: "See corresponding Defect".} = OverflowDefect
|
||||
AccessViolationError* {.deprecated: "See corresponding Defect".} = AccessViolationDefect
|
||||
AssertionError* {.deprecated: "See corresponding Defect".} = AssertionDefect
|
||||
OutOfMemError* {.deprecated: "See corresponding Defect".} = OutOfMemDefect
|
||||
IndexError* {.deprecated: "See corresponding Defect".} = IndexDefect
|
||||
when not defined(nimPreviewSlimSystem):
|
||||
type
|
||||
ArithmeticError* {.deprecated: "See corresponding Defect".} = ArithmeticDefect
|
||||
DivByZeroError* {.deprecated: "See corresponding Defect".} = DivByZeroDefect
|
||||
OverflowError* {.deprecated: "See corresponding Defect".} = OverflowDefect
|
||||
AccessViolationError* {.deprecated: "See corresponding Defect".} = AccessViolationDefect
|
||||
AssertionError* {.deprecated: "See corresponding Defect".} = AssertionDefect
|
||||
OutOfMemError* {.deprecated: "See corresponding Defect".} = OutOfMemDefect
|
||||
IndexError* {.deprecated: "See corresponding Defect".} = IndexDefect
|
||||
|
||||
FieldError* {.deprecated: "See corresponding Defect".} = FieldDefect
|
||||
RangeError* {.deprecated: "See corresponding Defect".} = RangeDefect
|
||||
StackOverflowError* {.deprecated: "See corresponding Defect".} = StackOverflowDefect
|
||||
ReraiseError* {.deprecated: "See corresponding Defect".} = ReraiseDefect
|
||||
ObjectAssignmentError* {.deprecated: "See corresponding Defect".} = ObjectAssignmentDefect
|
||||
ObjectConversionError* {.deprecated: "See corresponding Defect".} = ObjectConversionDefect
|
||||
FloatingPointError* {.deprecated: "See corresponding Defect".} = FloatingPointDefect
|
||||
FloatInvalidOpError* {.deprecated: "See corresponding Defect".} = FloatInvalidOpDefect
|
||||
FloatDivByZeroError* {.deprecated: "See corresponding Defect".} = FloatDivByZeroDefect
|
||||
FloatOverflowError* {.deprecated: "See corresponding Defect".} = FloatOverflowDefect
|
||||
FloatUnderflowError* {.deprecated: "See corresponding Defect".} = FloatUnderflowDefect
|
||||
FloatInexactError* {.deprecated: "See corresponding Defect".} = FloatInexactDefect
|
||||
DeadThreadError* {.deprecated: "See corresponding Defect".} = DeadThreadDefect
|
||||
NilAccessError* {.deprecated: "See corresponding Defect".} = NilAccessDefect
|
||||
FieldError* {.deprecated: "See corresponding Defect".} = FieldDefect
|
||||
RangeError* {.deprecated: "See corresponding Defect".} = RangeDefect
|
||||
StackOverflowError* {.deprecated: "See corresponding Defect".} = StackOverflowDefect
|
||||
ReraiseError* {.deprecated: "See corresponding Defect".} = ReraiseDefect
|
||||
ObjectAssignmentError* {.deprecated: "See corresponding Defect".} = ObjectAssignmentDefect
|
||||
ObjectConversionError* {.deprecated: "See corresponding Defect".} = ObjectConversionDefect
|
||||
FloatingPointError* {.deprecated: "See corresponding Defect".} = FloatingPointDefect
|
||||
FloatInvalidOpError* {.deprecated: "See corresponding Defect".} = FloatInvalidOpDefect
|
||||
FloatDivByZeroError* {.deprecated: "See corresponding Defect".} = FloatDivByZeroDefect
|
||||
FloatOverflowError* {.deprecated: "See corresponding Defect".} = FloatOverflowDefect
|
||||
FloatUnderflowError* {.deprecated: "See corresponding Defect".} = FloatUnderflowDefect
|
||||
FloatInexactError* {.deprecated: "See corresponding Defect".} = FloatInexactDefect
|
||||
DeadThreadError* {.deprecated: "See corresponding Defect".} = DeadThreadDefect
|
||||
NilAccessError* {.deprecated: "See corresponding Defect".} = NilAccessDefect
|
||||
|
|
|
|||
156
lib/system/indices.nim
Normal file
156
lib/system/indices.nim
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
type
|
||||
BackwardsIndex* = distinct int ## Type that is constructed by `^` for
|
||||
## reversed array accesses.
|
||||
## (See `^ template <#^.t,int>`_)
|
||||
|
||||
template `^`*(x: int): BackwardsIndex = BackwardsIndex(x)
|
||||
## Builtin `roof`:idx: operator that can be used for convenient array access.
|
||||
## `a[^x]` is a shortcut for `a[a.len-x]`.
|
||||
##
|
||||
## ```
|
||||
## let
|
||||
## a = [1, 3, 5, 7, 9]
|
||||
## b = "abcdefgh"
|
||||
##
|
||||
## echo a[^1] # => 9
|
||||
## echo b[^2] # => g
|
||||
## ```
|
||||
|
||||
proc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline.} =
|
||||
system.`[]`(s, s.len - int(i))
|
||||
|
||||
proc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline.} =
|
||||
a[Idx(a.len - int(i) + int low(a))]
|
||||
proc `[]`*(s: string; i: BackwardsIndex): char {.inline.} = s[s.len - int(i)]
|
||||
|
||||
proc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline.} =
|
||||
system.`[]`(s, s.len - int(i))
|
||||
proc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline.} =
|
||||
a[Idx(a.len - int(i) + int low(a))]
|
||||
proc `[]`*(s: var string; i: BackwardsIndex): var char {.inline.} = s[s.len - int(i)]
|
||||
|
||||
proc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline.} =
|
||||
system.`[]=`(s, s.len - int(i), x)
|
||||
proc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline.} =
|
||||
a[Idx(a.len - int(i) + int low(a))] = x
|
||||
proc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline.} =
|
||||
s[s.len - int(i)] = x
|
||||
|
||||
template `..^`*(a, b: untyped): untyped =
|
||||
## A shortcut for `.. ^` to avoid the common gotcha that a space between
|
||||
## '..' and '^' is required.
|
||||
a .. ^b
|
||||
|
||||
template `..<`*(a, b: untyped): untyped =
|
||||
## A shortcut for `a .. pred(b)`.
|
||||
## ```
|
||||
## for i in 5 ..< 9:
|
||||
## echo i # => 5; 6; 7; 8
|
||||
## ```
|
||||
a .. (when b is BackwardsIndex: succ(b) else: pred(b))
|
||||
|
||||
template `[]`*(s: string; i: int): char = arrGet(s, i)
|
||||
template `[]=`*(s: string; i: int; val: char) = arrPut(s, i, val)
|
||||
|
||||
template `^^`(s, i: untyped): untyped =
|
||||
(when i is BackwardsIndex: s.len - int(i) else: int(i))
|
||||
|
||||
template spliceImpl(s, a, L, b: untyped): untyped =
|
||||
# make room for additional elements or cut:
|
||||
var shift = b.len - max(0,L) # ignore negative slice size
|
||||
var newLen = s.len + shift
|
||||
if shift > 0:
|
||||
# enlarge:
|
||||
setLen(s, newLen)
|
||||
for i in countdown(newLen-1, a+b.len): movingCopy(s[i], s[i-shift])
|
||||
else:
|
||||
for i in countup(a+b.len, newLen-1): movingCopy(s[i], s[i-shift])
|
||||
# cut down:
|
||||
setLen(s, newLen)
|
||||
# fill the hole:
|
||||
for i in 0 ..< b.len: s[a+i] = b[i]
|
||||
|
||||
proc `[]`*[T, U: Ordinal](s: string, x: HSlice[T, U]): string {.inline.} =
|
||||
## Slice operation for strings.
|
||||
## Returns the inclusive range `[s[x.a], s[x.b]]`:
|
||||
## ```
|
||||
## var s = "abcdef"
|
||||
## assert s[1..3] == "bcd"
|
||||
## ```
|
||||
let a = s ^^ x.a
|
||||
let L = (s ^^ x.b) - a + 1
|
||||
result = newString(L)
|
||||
for i in 0 ..< L: result[i] = s[i + a]
|
||||
|
||||
proc `[]=`*[T, U: Ordinal](s: var string, x: HSlice[T, U], b: string) =
|
||||
## Slice assignment for strings.
|
||||
##
|
||||
## If `b.len` is not exactly the number of elements that are referred to
|
||||
## by `x`, a `splice`:idx: is performed:
|
||||
##
|
||||
runnableExamples:
|
||||
var s = "abcdefgh"
|
||||
s[1 .. ^2] = "xyz"
|
||||
assert s == "axyzh"
|
||||
|
||||
var a = s ^^ x.a
|
||||
var L = (s ^^ x.b) - a + 1
|
||||
if L == b.len:
|
||||
for i in 0..<L: s[i+a] = b[i]
|
||||
else:
|
||||
spliceImpl(s, a, L, b)
|
||||
|
||||
proc `[]`*[Idx, T; U, V: Ordinal](a: array[Idx, T], x: HSlice[U, V]): seq[T] =
|
||||
## Slice operation for arrays.
|
||||
## Returns the inclusive range `[a[x.a], a[x.b]]`:
|
||||
## ```
|
||||
## var a = [1, 2, 3, 4]
|
||||
## assert a[0..2] == @[1, 2, 3]
|
||||
## ```
|
||||
let xa = a ^^ x.a
|
||||
let L = (a ^^ x.b) - xa + 1
|
||||
result = newSeq[T](L)
|
||||
for i in 0..<L: result[i] = a[Idx(i + xa)]
|
||||
|
||||
proc `[]=`*[Idx, T; U, V: Ordinal](a: var array[Idx, T], x: HSlice[U, V], b: openArray[T]) =
|
||||
## Slice assignment for arrays.
|
||||
## ```
|
||||
## var a = [10, 20, 30, 40, 50]
|
||||
## a[1..2] = @[99, 88]
|
||||
## assert a == [10, 99, 88, 40, 50]
|
||||
## ```
|
||||
let xa = a ^^ x.a
|
||||
let L = (a ^^ x.b) - xa + 1
|
||||
if L == b.len:
|
||||
for i in 0..<L: a[Idx(i + xa)] = b[i]
|
||||
else:
|
||||
sysFatal(RangeDefect, "different lengths for slice assignment")
|
||||
|
||||
proc `[]`*[T; U, V: Ordinal](s: openArray[T], x: HSlice[U, V]): seq[T] =
|
||||
## Slice operation for sequences.
|
||||
## Returns the inclusive range `[s[x.a], s[x.b]]`:
|
||||
## ```
|
||||
## var s = @[1, 2, 3, 4]
|
||||
## assert s[0..2] == @[1, 2, 3]
|
||||
## ```
|
||||
let a = s ^^ x.a
|
||||
let L = (s ^^ x.b) - a + 1
|
||||
newSeq(result, L)
|
||||
for i in 0 ..< L: result[i] = s[i + a]
|
||||
|
||||
proc `[]=`*[T; U, V: Ordinal](s: var seq[T], x: HSlice[U, V], b: openArray[T]) =
|
||||
## Slice assignment for sequences.
|
||||
##
|
||||
## If `b.len` is not exactly the number of elements that are referred to
|
||||
## by `x`, a `splice`:idx: is performed.
|
||||
runnableExamples:
|
||||
var s = @"abcdefgh"
|
||||
s[1 .. ^2] = @"xyz"
|
||||
assert s == @"axyzh"
|
||||
|
||||
let a = s ^^ x.a
|
||||
let L = (s ^^ x.b) - a + 1
|
||||
if L == b.len:
|
||||
for i in 0 ..< L: s[i+a] = b[i]
|
||||
else:
|
||||
spliceImpl(s, a, L, b)
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
## Default iterators for some Nim types.
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue